initool-smbconf-V10添加对Win10共享访问协议控制

#!/bin/bash
###
 # @Author: huangjinbang
 # @AuthorEmail: huangjinbang1996@163.com
 # @Date: 2023-4-12 18:52:45
 # @LastEditors: huangjinbang 
 # @LastEditorsEmail: huangjinbang1996@163.com
 # @LastEditTime: 2024-12-27 17:25:20
 # @FilePath: initool-smbconf-V10添加对Win10共享访问协议控制.sh
 # @Description: 
 # chatgpt shell  读取smbd服务配置,也实现插入或者剔除某项options配置,initool-smbconf-V10添加对Win10共享访问协议控制
 # smb共享,1.服务端设置一具有密码的smb用户,取消匿名用户访问
### 

#################################################################
#  default默认设置脚本环境设置,可以引入下
set +a
export LANG=en_US.utf8
export LANGUAGE='en_US:en'
curPath=$(readlink -f "$(dirname "$0")")    # 获取文件所在文件夹绝对路径(或当鼠标点击文件运行的时候)
#记录本脚本名
curScript=$0

echo "Current user: $USER"
echo "User using whoami: $(whoami)"
echo "UID of current user: $UID"
echo "User running this script: $(ps -o user= -p $$)"
echo -e "所有参数:$@   当前进程:$$ 当前路径:$curPath"
# if [ ".$1" = ".--help" ]; then
#     echo '  -v, --version   display version information'
#     echo '  -h, --help      display usage help page (this one)'
#     echo '  -d, --debug     display shell trace information'
#     exit 0
# fi
# 开启调试模式
# if [ ".$1" = ".-d" ] || [ ".$1" = ".--debug" ]; then
if [ ".$1" = ".--debug" ]; then
    shift
    # 设置 PS4 显示行号,$LINENO 表示当前行号
    export PS4='+${LINENO}: '
    set -x
fi

# # ###bash内置命令 type getopts
# optstring是一个字符串,包含一个可以为getopts命令识别的选项名称列表。我们让s表示一个字符,其中语法为:
# 选项内容	说明
#       :	optsring如果以:开头,表示是静默模式,忽略一般错误消息
#       s	有效选项并且后面不带参数值
#       s:	有效选项并且后面必须带参数值
# while getopts 'r: h d' OPT;do
#     case "${OPT}" in 
#         "r") echo rrrr ;;
#         "d") echo dddd ;;
#         "h") echo "here is help";help ;;
#         "?") echo "here is ?";help ;;
#     esac
# done
#################################################################


# 路径为绝对路径最好,或与本文件相对路径
CONFIG_FILE="/etc/samba/smb.conf"
# CONFIG_FILE="./smb.conf"
declare -a sections_save
declare -A section_key_value

function read_ini_file {
    local config_file="$1"
    local current_section=""
    while read -r line; do
        line="${line#"${line%%[![:space:]]*}"}" # 去除行首空白字符
        # line="${line%"${line##*[![:space:]]}"}" # 去除行末空白字符
        if [[ "$line" =~ ^[[:space:]]*\;.*$ ]]; then
            # 行非空字符以注释符号;开头,忽略
            continue
        elif [[ "$line" =~ ^[[:space:]]*\#.*$ ]]; then
            # 行非空字符以注释符号#开头,忽略
            continue
        elif [[ "$line" =~ ^\[.*\]$ ]]; then
            # 节点名称
            current_section="${line#\[}"
            current_section="${current_section%*\]}"
            sections_save+=("'${current_section}'")
        elif [[ "$line" =~ [[[:space:]]*[[:graph:]]*[[:space:]]*]*\={1}[[:space:]]*.*$ ]]; then
            # 键值对
            local key="${line%%=*}"
            key="${key#"${key%%[![:space:]]*}"}" # 去除键名左侧空白字符
            key="${key%"${key##*[![:space:]]}"}" # 去除键名右侧空白字符
            local value="${line#*=}"
            value="${value#"${value%%[![:space:]]*}"}" # 去除键值左侧空白字符
            value="${value%"${value##*[![:space:]]}"}" # 去除键值右侧空白字符
            # echo "'${current_section}'_'${key}'='${value}'"
            section_key_value["'${current_section}'_'${key}'"]="'${value}'"
        fi
    done < "$config_file"
    

}

function add_section_value {
    local config_file="$1"
    local section_name="$2"
    local key_name="$3"
    local value="$4"
    local current_section=""
    local found_section=false
    local found_key=false
    while read -r line; do
        line="${line#"${line%%[![:space:]]*}"}" # 去除行首空白字符
        # line="${line%"${line##*[![:space:]]}"}" # 去除行末空白字符
        if [[ "$line" =~ ^\;.*$ ]]; then
            # 行非空字符以注释符号;开头,忽略
            continue
        elif [[ "$line" =~ ^[[:space:]]*\#.*$ ]]; then
            # 行非空字符以注释符号#开头,忽略
            continue
        elif [[ "$line" =~ ^\[.*\]$ ]]; then
            # 节点名称
            current_section="${line#\[}"
            current_section="${current_section%*\]}"
            if [[ "${current_section}" == "${section_name}" ]]; then
                found_section=true
            fi
        elif [[ "$line" =~ [[[:space:]]*[[:graph:]]*[[:space:]]*]*\={1}[[:space:]]*.*$ ]]; then
            # 键值对
            local key="${line%%=*}"
            key="${key#"${key%%[![:space:]]*}"}" # 去除键名左侧空白字符
            key="${key%"${key##*[![:space:]]}"}" # 去除键名右侧空白字符
            local value_="${value}"
            value_="${value_#"${value_%%*[![:space:]]}"}" # 去除键值右侧空白字符
            value_="${value_%"${value_##*[![:space:]]}"}" # 去除键值左侧空白字符
            if [[ "${current_section}" == "${section_name}" && "${key}" == "${key_name}" ]]; then
                # 节点存在,键值对存在
                found_key=true
            fi
        fi
    done < "$config_file"
    # 如果该节点存在且该键不存在,则在该节点下添加键值对
    if [[ "${found_key}" == false ]]; then
        sed -i "/^[[:space:]]*\[${section_name}\]/a ${key_name}=${value}" "${config_file}"
    fi
    # 如果该节点不存在,则添加节点
    if [[ "${found_section}" == false ]]; then
        echo -e "\n[${section_name}]" >> "${config_file}"
        echo -e "${key_name} = ${value}" >> "${config_file}"
    fi
}

########旧版本
# ##chatGPT 改过的 速度有点慢
# function add_section_value {
#     local config_file="$1"
#     local section_name="$2"
#     local key_name="$3"
#     local value="$4"
#     local current_section=""
#     local found_section=false
#     local found_key=false
#     # 去除行首空白字符和行末空白字符的正则表达式
#     local trim_regex='^[[:space:]]*|\([[:space:]]*\)$'
#     while read -r line; do
#         # 去除行首空白字符和行末空白字符
#         line="$(echo "${line}" | sed -e "s/${trim_regex}//")"
#         if [[ "$line" =~ ^\;.*$ || "$line" =~ ^[[:space:]]*\#.*$ ]]; then
#             # 行非空字符以注释符号;或#开头,忽略
#             continue
#         elif [[ "$line" =~ ^\[.*\]$ ]]; then
#             # 节点名称
#             current_section="${line#\[}"
#             current_section="${current_section%\]}"
#             if [[ "${current_section}" == "${section_name}" ]]; then
#                 found_section=true
#             fi
#         elif [[ "$line" =~ ^[[:space:]]*([^=[:space:]]+)[[:space:]]*=[[:space:]]*(.*)$ ]]; then
#             # 键值对
#             local key="${BASH_REMATCH[1]}"
#             local value_="${BASH_REMATCH[2]}"
#             # 去除键名和键值两侧空白字符
#             key="$(echo "${key}" | sed -e "s/${trim_regex}//")"
#             value_="$(echo "${value_}" | sed -e "s/${trim_regex}//")"
#             if [[ "${current_section}" == "${section_name}" && "${key}" == "${key_name}" ]]; then
#                 # 节点存在,键值对存在
#                 found_key=true
#             fi
#         fi
#     done < "${config_file}"
#     # 如果该节点存在且该键不存在,则在该节点下添加键值对
#     if [[ "${found_key}" == false && "${found_section}" == true ]]; then
#         sed -i "/^[[:space:]]*\[${section_name}\]/a ${key_name}=${value}" "${config_file}"
#     fi
#     # 如果该节点不存在,则添加节点
#     if [[ "${found_section}" == false ]]; then
#         echo -e "\n[${section_name}]" >> "${config_file}"
#         echo -e "${key_name} = ${value}" >> "${config_file}"
#     fi
# }

########旧版本
# ##chatGPT实现(需要替换文件)
# function delete_section {
#     local config_file="$1"
#     local section_name="$2"
#     local in_section=false
#     local tmp_file="$1".tmp # 创建临时文件
#     while IFS='' read -r line || [[ -n "$line" ]]; do
#         # 判断当前行是否为目标节点
#         if [[ "$line" =~ ^\[$section_name\] ]]; then
#             in_section=true
#         # 判断当前行是否为其他节点
#         elif [[ "$line" =~ ^\[.*\] ]]; then
#             in_section=false
#         fi
#         # 如果不在目标节点中,则将当前行写入临时文件中
#         if [[ "$in_section" == false ]]; then
#             echo "$line" >> "$tmp_file"
#         fi
#     done < "$config_file"
#     # 将临时文件中的内容覆盖到原配置文件中
#     cat "$tmp_file" > "$config_file"
#     rm "$tmp_file" # 删除临时文件
# }

########旧版本
# # 定义函数,用于删除指定部分中的指定键值对
# function delete_ini_key {
#     local section_name=$2
#     local key_name=$3
#     local ini_file=$1
#     local current_section=""
#     local section_found=false
#     # 逐行读取INI文件
#     while read line; do
#         # 判断是否是节的行
#         if [[ $line == \[*\] ]]; then
#             current_section="${line#\[}"
#             current_section="${current_section%\]}"
#             # 如果找到了目标部分,将标志位置为true
#             if [[ $current_section == $section_name ]]; then
#                 section_found=true
#             fi
#         fi
#         # 如果找到了目标部分,继续查找键值对
#         if [[ $section_found == true ]]; then
#             # 查找键名并删除该行
#             if [[ $line == "$key_name="* ]]; then
#                 sed -i "/$key_name=/d" "$ini_file"    #bug
#             fi
#         fi
#         # 如果已经处理完目标部分,则退出函数
#         if [[ $section_found == true ]] && [[ $line == \[*] ]]; then
#             return
#         fi
#     done < "$ini_file"
# }

# 定义函数,用于删除指定部分中的指定键值对  bug1
function delete_ini_key {
    local section_name=$1
    local key_name=$2
    local ini_file=$3
    # 在指定的节中查找并删除键值对;注意:匹配内容从[] 到[,下一段从]开始;若有相同内容[s1]..[s1]..[s1],则内容[s1]..[s1]分割..分割[s1],则1和3能被处理,2不被处理
    sed -i "/^[[:space:]]*\[${section_name}\][[:space:]]*$/,/^[[:space:]]*\[.*\][[:space:]]*/ {/^[[:space:]]*${key_name}[[:space:]]*=/d;}" "$ini_file"
}

# 定义函数,用于删除指定节点    bug1
function delete_section {
    local section_name=$1
    local ini_file=$2
    # 在指定的节中查找并删除键值对;注意:匹配内容从[] 到[,下一段从]开始;若有相同内容[s1]..[s1]..[s1],则内容[s1]..[s1]分割..分割[s1],则1和3能被处理,2不被处理
    sed -i "/^[[:space:]]*\[${section_name}\][[:space:]]*$/,/^[[:space:]]*\[.*\][[:space:]]*/ {/.*=/d;}" "$ini_file"
    sed -i "/^[[:space:]]*\[${section_name}\][[:space:]]*/d" "$ini_file"
}

# 定义函数,用于更改指定部分中的指定键对应的键值 bug1
function change_ini_value {
    local section_name=$1
    local key_name=$2
    local new_value=$3
    local ini_file=$4
    # 查找指定节中指定的键,并将其对应的值修改为新值;;注意:匹配内容从[] 到[,下一段从]开始;若有相同内容[s1]..[s1]..[s1],则内容[s1]..[s1]分割..分割[s1],则1和3能被处理,2不被处理
    sed -i "/^[[:space:]]*\[${section_name}\][[:space:]]*$/,/^[[:space:]]*\[.*\][[:space:]]*/ {s/^\([[:space:]]*${key_name}[[:space:]]*=[[:space:]]*\).*/\1$new_value/}" "$ini_file"
}

########旧版本
# function get_config_value {
#     local config_file="$1"
#     local section_name="$2"
#     local key_name="$3"
#     local current_section=""
#     while read -r line; do
#         line="${line#"${line%%[![:space:]]*}"}" # 去除行首空白字符
#         # line="${line%"${line##*[![:space:]]}"}" # 去除行末空白字符
#         if [[ "$line" =~ ^[[:space:]]*\;.*$ ]]; then
#             # 行非空字符以注释符号;开头,忽略
#             continue
#         elif [[ "$line" =~ ^[[:space:]]*\#.*$ ]]; then
#             # 行非空字符以注释符号#开头,忽略
#             continue
#         elif [[ "$line" =~ ^\[.*\]$ ]]; then
#             # 节点名称
#             current_section="${line#\[}"
#             current_section="${current_section%*\]}"
#         elif [[ "$line" =~ [[[:space:]]*[[:graph:]]*[[:space:]]*]*\={1}[[:space:]]*.*$ ]]; then
#             # 键值对
#             local key="${line%%=*}"
#             key="${key#"${key%%[![:space:]]*}"}" # 去除键名左侧空白字符
#             key="${key%"${key##*[![:space:]]}"}" # 去除键名右侧空白字符
#             local value="${line#*=}"
#             value="${value#"${value%%[![:space:]]*}"}" # 去除键值左侧空白字符
#             value="${value%"${value##*[![:space:]]}"}" # 去除键值右侧空白字符
#             if [[ "${current_section}" == "${section_name}" && "${key}" == "${key_name}" ]]; then
#                 echo "${value}"
#                 return 0
#             fi
#         fi
#     done < "$config_file"
#     return 1
# }

# ##chatGPT 
function get_config_value {
    local config_file="$1"
    local section_name="$2"
    local key_name="$3"
    local current_section=""
    while read -r line; do
        line="${line#"${line%%[![:space:]]*}"}" # 去除行首空白字符
        if [[ "$line" =~ ^[[:space:]]*[\;\#] ]]; then
            # 行以注释符号;或#开头,忽略
            continue
        elif [[ "$line" =~ ^\[.*\]$ ]]; then
            # 节点名称
            current_section="${line#\[}"
            current_section="${current_section%\]}"
        elif [[ "$line" =~ ^[[:space:]]*${key_name}[[:space:]]*=[[:space:]]*\"(.*)\"[[:space:]]* ]]; then
            # 双引号包含的值
            if [[ "${current_section}" == "${section_name}" ]]; then
                echo "${BASH_REMATCH[1]}"
                return 0
            fi
        elif [[ "$line" =~ ^[[:space:]]*${key_name}[[:space:]]*=[[:space:]]*\'(.*)\'[[:space:]]* ]]; then
            # 单引号包含的值
            if [[ "${current_section}" == "${section_name}" ]]; then
                echo "${BASH_REMATCH[1]}"
                return 0
            fi
        elif [[ "$line" =~ ^[[:space:]]*${key_name}[[:space:]]*=[[:space:]]*(.*) ]]; then
            # 普通键值对的值
            if [[ "${current_section}" == "${section_name}" ]]; then
                echo "${BASH_REMATCH[1]}"
                return 0
            fi
        fi
    done < "$config_file"
}

######################################################使用例子
# # 读取配置文件
read_ini_file "$CONFIG_FILE"

# # 查询指定节点的指定配置项 ok
# value=$(get_config_value "$CONFIG_FILE" "s1" "s")
# echo "s1.s=${value}"

# update- 增 删 改

# 增 添加节点,键值对 ok
# add_section_value "$CONFIG_FILE" "s1" "1" "4545"
# add_section_value "$CONFIG_FILE" "s1" "2" "4545"
# add_section_value "$CONFIG_FILE" "s1" "3" "4545"
# add_section_value "$CONFIG_FILE" "s3" "1" "4545"
# add_section_value "$CONFIG_FILE" "s3" "2" "1235"
# add_section_value "$CONFIG_FILE" "s3" "3" "453345"
# add_section_value "$CONFIG_FILE" "s2" "1" "5234"
# add_section_value "$CONFIG_FILE" "s2" "2" "5234"
# add_section_value "$CONFIG_FILE" "s2" "3" "5234"
# add_section_value "$CONFIG_FILE" "faf" "s1" "545646"
# add_section_value "$CONFIG_FILE" "s3" "s2" "4564"
# add_section_value "$CONFIG_FILE" "s6" "s" "45612414"



# # 调用函数删除指定section部分中的指定option键value值对 ok
# delete_ini_key "s3" "s2" "$CONFIG_FILE"
# delete_ini_key "s3" "2" "$CONFIG_FILE"

# # 调用函数删除指定section节点 
# delete_section "s1" "$CONFIG_FILE"  

# # 改
# change_ini_value "s3" "s2" "5251" "$CONFIG_FILE"

## section  key value关联
# echo ${sections_save[@]}
# echo ${!sections_save[@]}
# echo ${#sections_save[@]}

# ## 查看关联数组内数据,获取引索
# for index in "${!section_key_value[@]}";
# do
#     # echo $index
#     # echo "${index}=${section_key_value["${index}"]}"
#     echo "${index}" | grep "${sections_save[0]}"
# done

######################################################
# V10添加对Win10共享访问协议版本控制  https://blog.csdn.net/u013992330/article/details/107123229?spm=1001.2101.3001.6650.5&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-5-107123229-blog-114948840.235%5Ev43%5Epc_blog_bottom_relevance_base7&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-5-107123229-blog-114948840.235%5Ev43%5Epc_blog_bottom_relevance_base7&utm_relevant_index=10
##  smbclient -L  IP
##  smbclient 报错:protocol negotiation failed: NT_STATUS_CONNECTION_RESET

# delete_ini_key "global" "client min protocol" "$CONFIG_FILE"
# delete_ini_key "global" "client max protocol" "$CONFIG_FILE"

value=$(get_config_value "$CONFIG_FILE" "global" "client min protocol" )
echo "global.client min protocol=${value}"
value=$(get_config_value "$CONFIG_FILE" "global" "client max protocol" )
echo "global.client max protocol=${value}"


add_section_value "$CONFIG_FILE" "global" "client min protocol" "CORE"
add_section_value "$CONFIG_FILE" "global" "client max protocol" "SMB3"

value=$(get_config_value "$CONFIG_FILE" "global" "client min protocol" )
echo "global.client min protocol=${value}"
value=$(get_config_value "$CONFIG_FILE" "global" "client max protocol" )
echo "global.client max protocol=${value}"

sudo systemctl restart smbd.service
posted @ 2024-12-19 17:41  ThreeFlower  阅读(11)  评论(0)    收藏  举报