F36 live has build tools! but it does not connect wifi

I can’t comment on your ‘updated script’ since you are repeatedly posting images instead of text.

It is always suggested that users post text using the </> Preformatted text tags so readers can see the entire text posted (not cut off at screen edge as your images do), formatting is retained as seen on your screen, and so segments of interest can be copied for quoting or comments. It also allows much less bandwidth and data usage to post the full script when compared to an image.

I modified the script that has access denied to write to /etc/resolv.conf

/usr/sbin/dhclient-script

Here I paste only the edited fragment

# Takes one argument - temporary resolv.conf file
change_resolv_conf ()
{
    options=$(grep '^[\ \       ]*option' "${RESOLVCONF}" 2>/dev/null);
    if [[ -n "${options}" ]]; then
       # merge options from existing resolv.conf with specified resolv.conf content
       newres="${options}"$'\n'$(grep -vF "${options}" "${1}");
    else
       newres=$(cat "${1}");
    fi;
## Edited for yascker
    echo ""
    echo ""
    echo ""
    echo "show config impossible to write in /etc/resolv.conf, due to lack of permission"
    echo "${newres}"
    echo ""
    echo ""
    echo "I'm trying to write the file to a location where root be able to /home/liveuser/resolv.conf"
    echo "${newres}" > /home/liveuser/resolv.conf
    echo ""
    echo ""
## Edited for yascker
    eval $(echo "${newres}" > "${RESOLVCONF}"; echo "status=$?")
    if [[ $status -eq 0 ]]; then
        logger -p local7.notice -t "NET" -i "${0} : updated ${RESOLVCONF}";
        [[ -e /var/run/nscd/socket ]] && /usr/sbin/nscd -i hosts; # invalidate cache
    fi;
    return $status;
}



And here the result of execution

[root@localhost-live liveuser]# dhclient -x
Removed stale PID file
[root@localhost-live liveuser]# dhclient -v wlp3s0
Internet Systems Consortium DHCP Client 4.4.2-P1
Copyright 2004-2021 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/wlp3s0/b4:82:fe:3c:47:13
Sending on   LPF/wlp3s0/b4:82:fe:3c:47:13
Sending on   Socket/fallback
DHCPREQUEST for 192.168.0.116 on wlp3s0 to 255.255.255.255 port 67 (xid=0xcedf9979)
DHCPACK of 192.168.0.116 from 192.168.0.1 (xid=0xcedf9979)



show config impossible to write in /etc/resolv.conf, due to lack of permission
options edns0 trust-ad
; generated by /usr/sbin/dhclient-script
search local
nameserver 192.168.0.1


I am trying to write the file to a location where root be able to /home/liveuser/resolv.conf
/usr/sbin/dhclient-script: line 714: /home/liveuser/resolv.conf: Permission denied


/usr/sbin/dhclient-script: line 718: /etc/resolv.conf: Permission denied
/etc/dhcp/dhclient.d/chrony.sh: line 14: /run/chrony-dhcp/wlp3s0.sources: Permission denied
bound to 192.168.0.116 -- renewal in 40316 seconds.


And these are the script permissions and resolv.conf

[root@localhost-live liveuser]# ls -l /usr/sbin/dhclient-script
-rwxr-xr-x. 1 root root 34041 Nov  8 05:39 /usr/sbin/dhclient-script

[root@localhost-live liveuser]# ls -l /etc/resolv.conf 
lrwxrwxrwx. 1 root root 39 May  4  2022 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf


And when putting together this answer, check the permissions of the symbolic link, and it turns out that the owner is not root, but… shouldn’t I be able to write it the same?

[root@localhost-live liveuser]# ls -l /run/systemd/resolve/stub-resolv.conf
-rw-r--r--. 1 systemd-resolve systemd-resolve 921 Nov  8  2022 /run/systemd/resolve/stub-resolv.conf

do

chown root:root /run/systemd/resolve/stub-resolv.conf

Now the script can apply the new script settings
Tomorrow I will review how all this is in Arch Linux, to compare

I would’ve thought you would be able to:
sudo dnf download --destdir=. package-name --resolve
this downloads packagename and it’s dependencies into the current directory, please change the destination directory to what you would like to use.
Copy them to what you need and and then manually install sudo dnf install ./*.rpm or similiar.

Are you sure you weren’t looking for dhcpcd?

Depending on what you’re trying to do/learn you may also want to read up on dhcpcd, systemd-resolved, systemd-networkd and Network-Manager.

Thanks

I went looking for any difference in Archlinux and found that dhclent-script are different.
The Arch one has about 400 lines and the F36 900 lines.
So what I did was take it to F36 and put it in your place: /usr/sbin/dhclient-script
And after that I connected via wpa_supplicant and then
# dhclient -v wlp3s0

And to my surprise it successfully connected to the internet

The /etc/resolv.conf file took the configuration injected by the script with no problems…

Arch’s dhclient-script is:

#!/bin/bash
# dhclient-script for Linux. Dan Halbert, March, 1997.
# Updated for Linux 2.[12] by Brian J. Murrell, January 1999.
# No guarantees about this. I'm a novice at the details of Linux
# networking.

# Notes:

# 0. This script is based on the netbsd script supplied with dhcp-970306.

# 1. ifconfig down apparently deletes all relevant routes and flushes
# the arp cache, so this doesn't need to be done explicitly.

# 2. The alias address handling here has not been tested AT ALL.
# I'm just going by the doc of modern Linux ip aliasing, which uses
# notations like eth0:0, eth0:1, for each alias.

# 3. I have to calculate the network address, and calculate the broadcast
# address if it is not supplied. This might be much more easily done
# by the dhclient C code, and passed on.

# 4. TIMEOUT not tested. ping has a flag I don't know, and I'm suspicious
# of the $1 in its args.

# 5. Script refresh in 2017. The aliasing code was too convoluted and needs
# to go away. Migrated DHCPv4 script to ip command from iproute2 suite.
# This is based on Debian script with some tweaks. ifconfig is no longer
# used. Everything is done using ip tool from ip-route2.

# 'ip' just looks too weird. Also, we now have unit-tests! Those unit-tests
# overwirte this line to use a fake ip-echo tool. It's also convenient
# if your system holds ip tool in a non-standard location.
ip=/sbin/ip

# update /etc/resolv.conf based on received values
# This updated version mostly follows Debian script by Andrew Pollock et al.
make_resolv_conf() {
    local new_resolv_conf

    # DHCPv4
    if [ -n "$new_domain_search" ] || [ -n "$new_domain_name" ] ||
       [ -n "$new_domain_name_servers" ]; then
        new_resolv_conf=/etc/resolv.conf.dhclient-new
        rm -f $new_resolv_conf

        if [ -n "$new_domain_name" ]; then
            echo domain ${new_domain_name%% *} >>$new_resolv_conf
        fi

        if [ -n "$new_domain_search" ]; then
            if [ -n "$new_domain_name" ]; then
                domain_in_search_list=""
                for domain in $new_domain_search; do
                    if [ "$domain" = "${new_domain_name}" ] ||
                       [ "$domain" = "${new_domain_name}." ]; then
                        domain_in_search_list="Yes"
                    fi
                done
                if [ -z "$domain_in_search_list" ]; then
                    new_domain_search="$new_domain_name $new_domain_search"
                fi
            fi
            echo "search ${new_domain_search}" >> $new_resolv_conf
        elif [ -n "$new_domain_name" ]; then
            echo "search ${new_domain_name}" >> $new_resolv_conf
        fi

        if [ -n "$new_domain_name_servers" ]; then
            for nameserver in $new_domain_name_servers; do
                echo nameserver $nameserver >>$new_resolv_conf
            done
        else # keep 'old' nameservers
            sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p /etc/resolv.conf >>$new_resolv_conf
        fi

	if [ -f /etc/resolv.conf ]; then
	    chown --reference=/etc/resolv.conf $new_resolv_conf
	    chmod --reference=/etc/resolv.conf $new_resolv_conf
	fi
        mv -f $new_resolv_conf /etc/resolv.conf
    # DHCPv6
    elif [ -n "$new_dhcp6_domain_search" ] || [ -n "$new_dhcp6_name_servers" ]; then
        new_resolv_conf=/etc/resolv.conf.dhclient-new
        rm -f $new_resolv_conf

        if [ -n "$new_dhcp6_domain_search" ]; then
            echo "search ${new_dhcp6_domain_search}" >> $new_resolv_conf
        fi

        if [ -n "$new_dhcp6_name_servers" ]; then
            for nameserver in $new_dhcp6_name_servers; do
                # append %interface to link-local-address nameservers
                if [ "${nameserver##fe80::}" != "$nameserver" ] ||
                   [ "${nameserver##FE80::}" != "$nameserver" ]; then
                    nameserver="${nameserver}%${interface}"
                fi
                echo nameserver $nameserver >>$new_resolv_conf
            done
        else # keep 'old' nameservers
            sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p /etc/resolv.conf >>$new_resolv_conf
        fi

	if [ -f /etc/resolv.conf ]; then
            chown --reference=/etc/resolv.conf $new_resolv_conf
            chmod --reference=/etc/resolv.conf $new_resolv_conf
	fi
        mv -f $new_resolv_conf /etc/resolv.conf
    fi
}

# set host name
set_hostname() {
    local current_hostname

    if [ -n "$new_host_name" ]; then
        current_hostname=$(uname -n)

        # current host name is empty, '(none)' or 'localhost' or differs from new one from DHCP
        if [ -z "$current_hostname" ] ||
           [ "$current_hostname" = '(none)' ] ||
           [ "$current_hostname" = 'localhost' ] ||
           [ "$current_hostname" = "$old_host_name" ]; then
           if [ "$new_host_name" != "$old_host_name" ]; then
               sysctl -w kernel/hostname="$new_host_name"
           fi
        fi
    fi
}

# run given script
run_hook() {
    local script
    local exit_status
    script="$1"

    if [ -f $script ]; then
        . $script
    fi

    if [ -n "$exit_status" ] && [ "$exit_status" -ne 0 ]; then
        logger -p daemon.err "$script returned non-zero exit status $exit_status"
    fi

    return $exit_status
}

# run scripts in given directory
run_hookdir() {
    local dir
    local exit_status
    dir="$1"

    if [ -d "$dir" ]; then
        for script in $(run-parts --list $dir); do
            run_hook $script || true
            exit_status=$?
        done
    fi

    return $exit_status
}

# Must be used on exit.   Invokes the local dhcp client exit hooks, if any.
exit_with_hooks() {
    exit_status=$1

    # Source the documented exit-hook script, if it exists
    if ! run_hook /etc/dhclient-exit-hooks; then
        exit_status=$?
    fi

    # Now run scripts in the Debian-specific directory.
    if ! run_hookdir /etc/dhclient-exit-hooks.d; then
        exit_status=$?
    fi

    exit $exit_status
}

# This function was largely borrowed from dhclient-script that
# ships with Centos, authored by Jiri Popelka and David Cantrell
# of Redhat. Thanks guys.
add_ipv6_addr_with_DAD() {
    ${ip} -6 addr replace ${new_ip6_address}/${new_ip6_prefixlen} \
    dev ${interface} scope global valid_lft ${new_max_life} \
        preferred_lft ${new_preferred_life}

    if [ ${dad_wait_time} -le 0 ]
    then
        # if we're not waiting for DAD, assume we're good
        return 0
    fi

    # Repeatedly test whether newly added address passed
    # duplicate address detection (DAD)
    for i in $(seq 1 ${dad_wait_time}); do
        sleep 1 # give the DAD some time

        addr=$(${ip} -6 addr show dev ${interface} \
            | grep ${new_ip6_address}/${new_ip6_prefixlen})

        # tentative flag == DAD is still not complete
        tentative=$(echo "${addr}" | grep tentative)
        # dadfailed flag == address is already in use somewhere else
        dadfailed=$(echo "${addr}" | grep dadfailed)

        if [ -n "${dadfailed}" ] ; then
            # address was added with valid_lft/preferred_lft 'forever',
            # remove it
            ${ip} -6 addr del ${new_ip6_address}/${new_ip6_prefixlen} \
                dev ${interface}

            exit_with_hooks 3
        fi

        if [ -z "${tentative}" ] ; then
            if [ -n "${addr}" ]; then
                # DAD is over
                    return 0
            else
                # address was auto-removed (or not added at all)
                exit_with_hooks 3
            fi
        fi
    done

    return 0
}

# Invoke the local dhcp client enter hooks, if they exist.
run_hook /etc/dhclient-enter-hooks
run_hookdir /etc/dhclient-enter-hooks.d

# Execute the operation
case "$reason" in

    ### DHCPv4 Handlers

    MEDIUM|ARPCHECK|ARPSEND)
        # Do nothing
        ;;
    PREINIT)
        # The DHCP client is requesting that an interface be
        # configured as required in order to send packets prior to
        # receiving an actual address. - dhclient-script(8)

        # ensure interface is up
        ${ip} link set dev ${interface} up

        if [ -n "$alias_ip_address" ]; then
            # flush alias IP from interface
            ${ip} -4 addr flush dev ${interface} label ${interface}:0
        fi

        ;;

    BOUND|RENEW|REBIND|REBOOT)
        set_hostname

        if [ -n "$old_ip_address" ] && [ -n "$alias_ip_address" ] &&
           [ "$alias_ip_address" != "$old_ip_address" ]; then
            # alias IP may have changed => flush it
            ${ip} -4 addr flush dev ${interface} label ${interface}:0
        fi

        if [ -n "$old_ip_address" ] &&
           [ "$old_ip_address" != "$new_ip_address" ]; then
            # leased IP has changed => flush it
            ${ip} -4 addr flush dev ${interface} label ${interface}
        fi

        if [ -z "$old_ip_address" ] ||
           [ "$old_ip_address" != "$new_ip_address" ] ||
           [ "$reason" = "BOUND" ] || [ "$reason" = "REBOOT" ]; then
            # new IP has been leased or leased IP changed => set it
            ${ip} -4 addr add ${new_ip_address}${new_subnet_mask:+/$new_subnet_mask} \
                ${new_broadcast_address:+broadcast $new_broadcast_address} \
                dev ${interface} label ${interface}

            if [ -n "$new_interface_mtu" ]; then
                # set MTU
                ${ip} link set dev ${interface} mtu ${new_interface_mtu}
            fi

	    # if we have $new_rfc3442_classless_static_routes then we have to
	    # ignore $new_routers entirely
	    if [ ! "$new_rfc3442_classless_static_routes" ]; then
		    # set if_metric if IF_METRIC is set or there's more than one router
		    if_metric="$IF_METRIC"
		    if [ "${new_routers%% *}" != "${new_routers}" ]; then
			if_metric=${if_metric:-1}
		    fi

		    for router in $new_routers; do
			if [ "$new_subnet_mask" = "255.255.255.255" ]; then
			    # point-to-point connection => set explicit route
			    ${ip} -4 route add ${router} dev $interface >/dev/null 2>&1
			fi

			# set default route
			${ip} -4 route add default via ${router} dev ${interface} \
			    ${if_metric:+metric $if_metric} >/dev/null 2>&1

			if [ -n "$if_metric" ]; then
			    if_metric=$((if_metric+1))
			fi
		    done
	    fi
        fi

        if [ -n "$alias_ip_address" ] &&
           [ "$new_ip_address" != "$alias_ip_address" ]; then
            # separate alias IP given, which may have changed
            # => flush it, set it & add host route to it
            ${ip} -4 addr flush dev ${interface} label ${interface}:0
            ${ip} -4 addr add ${alias_ip_address}${alias_subnet_mask:+/$alias_subnet_mask} \
                dev ${interface} label ${interface}:0
            ${ip} -4 route add ${alias_ip_address} dev ${interface} >/dev/null 2>&1
        fi

        # update /etc/resolv.conf
        make_resolv_conf

        ;;

    EXPIRE|FAIL|RELEASE|STOP)
        if [ -n "$alias_ip_address" ]; then
            # flush alias IP
            ${ip} -4 addr flush dev ${interface} label ${interface}:0
        fi

        if [ -n "$old_ip_address" ]; then
            # flush leased IP
            ${ip} -4 addr flush dev ${interface} label ${interface}
        fi

        if [ -n "$alias_ip_address" ]; then
            # alias IP given => set it & add host route to it
            ${ip} -4 addr add ${alias_ip_address}${alias_subnet_mask:+/$alias_subnet_mask} \
                dev ${interface} label ${interface}:0
            ${ip} -4 route add ${alias_ip_address} dev ${interface} >/dev/null 2>&1
        fi

        ;;

    TIMEOUT)
        if [ -n "$alias_ip_address" ]; then
            # flush alias IP
            ${ip} -4 addr flush dev ${interface} label ${interface}:0
        fi

        # set IP from recorded lease
        ${ip} -4 addr add ${new_ip_address}${new_subnet_mask:+/$new_subnet_mask} \
            ${new_broadcast_address:+broadcast $new_broadcast_address} \
            dev ${interface} label ${interface}

        if [ -n "$new_interface_mtu" ]; then
            # set MTU
            ${ip} link set dev ${interface} mtu ${new_interface_mtu}
        fi

        # if there is no router recorded in the lease or the 1st router answers pings
        if [ -z "$new_routers" ] || ping -q -c 1 "${new_routers%% *}"; then
	    # if we have $new_rfc3442_classless_static_routes then we have to
	    # ignore $new_routers entirely
	    if [ ! "$new_rfc3442_classless_static_routes" ]; then
		    if [ -n "$alias_ip_address" ] &&
		       [ "$new_ip_address" != "$alias_ip_address" ]; then
			# separate alias IP given => set up the alias IP & add host route to it
			${ip} -4 addr add \
                              ${alias_ip_address}${alias_subnet_mask:+/$alias_subnet_mask} \
			      dev ${interface} label ${interface}:0
			${ip} -4 route add ${alias_ip_address} dev ${interface} >/dev/null 2>&1
		    fi

		    # set if_metric if IF_METRIC is set or there's more than one router
		    if_metric="$IF_METRIC"
		    if [ "${new_routers%% *}" != "${new_routers}" ]; then
			if_metric=${if_metric:-1}
		    fi

		    # set default route
		    for router in $new_routers; do
			${ip} -4 route add default via ${router} dev ${interface} \
			    ${if_metric:+metric $if_metric} >/dev/null 2>&1

			if [ -n "$if_metric" ]; then
			    if_metric=$((if_metric+1))
			fi
		    done
	    fi

            # update /etc/resolv.conf
            make_resolv_conf
        else
            # flush all IPs from interface
            ip -4 addr flush dev ${interface}
            exit_with_hooks 2
        fi

        ;;

    V6ONLY)
        if [ -n "$old_ip_address" ]; then
            # flush leased IP
            ${ip} -4 addr flush dev ${interface} label ${interface}
        fi

        ;;

    ### DHCPv6 Handlers
    # TODO handle prefix change: ?based on ${old_ip6_prefix} and ${new_ip6_prefix}?

    PREINIT6)
        # ensure interface is up
        ${ip} link set ${interface} up

        # We need to give the kernel some time to active interface
        interface_up_wait_time=5
        for i in $(seq 0 ${interface_up_wait_time})
        do
            ${ip} link show dev ${interface} | grep -q LOWER_UP 2>&1
            if [ $? -eq 0 ]; then
                break;
            fi
            sleep 1
        done

        # flush any stale global permanent IPs from interface
        ${ip} -6 addr flush dev ${interface} scope global permanent

        # Wait for duplicate address detection for this interface if the
        # --dad-wait-time parameter has been specified and is greater than
        # zero.
        if [ ${dad_wait_time} -gt 0 ]; then
            # Check if any IPv6 address on this interface is marked as
            # tentative.
            ${ip} addr show ${interface} | grep inet6 | grep tentative \
                &> /dev/null
            if [ $? -eq 0 ]; then
                # Wait for duplicate address detection to complete or for
                # the timeout specified as --dad-wait-time.
                for i in $(seq 0 $dad_wait_time)
                do
                    # We're going to poll for the tentative flag every second.
                    sleep 1
                    ${ip} addr show ${interface} | grep inet6 | grep tentative \
                        &> /dev/null
                    if [ $? -ne 0 ]; then
                        break;
                    fi
                done
            fi
        fi

        ;;

    BOUND6|RENEW6|REBIND6)
        if [ "${new_ip6_address}" ] && [ "${new_ip6_prefixlen}" ]; then
            # set leased IP
            add_ipv6_addr_with_DAD
        fi

        # update /etc/resolv.conf
        if [ "${reason}" = BOUND6 ] ||
           [ "${new_dhcp6_name_servers}" != "${old_dhcp6_name_servers}" ] ||
           [ "${new_dhcp6_domain_search}" != "${old_dhcp6_domain_search}" ]; then
            make_resolv_conf
        fi

        ;;

    DEPREF6)
        if [ -z "${cur_ip6_prefixlen}" ]; then
            exit_with_hooks 2
        fi

        # set preferred lifetime of leased IP to 0
        ${ip} -6 addr change ${cur_ip6_address}/${cur_ip6_prefixlen} \
            dev ${interface} scope global preferred_lft 0

        ;;

    EXPIRE6|RELEASE6|STOP6)
        if [ -z "${old_ip6_address}" ] || [ -z "${old_ip6_prefixlen}" ]; then
            exit_with_hooks 2
        fi

        # delete leased IP
        ${ip} -6 addr del ${old_ip6_address}/${old_ip6_prefixlen} \
            dev ${interface}

        ;;
esac

exit_with_hooks 0

Analyzing the Archlinux script and comparing it with the one from F36. I see that they are very different but I could notice that what it does is:
Instead of writing to /etc/resolv.conf what it does is create a new file called /etc/resolv.conf.dhclient-new (with the new DNS information)
Change the permissions taking the original as a reference with:

chown --reference=/etc/resolv.conf $new_resolv_conf
chmod --reference=/etc/resolv.conf $new_resolv_conf

Then delete the existing /etc/resolv.conf file
Then rename the new file created above /etc/resolv.conf.dhclient-new to /etc/resolv.conf.dhclient-new

Something like that I tried to replicate in the script and it worked correctly.

# Takes one argument - temporary resolv.conf file
change_resolv_conf ()
{
    options=$(grep '^[\ \	]*option' "${RESOLVCONF}" 2>/dev/null);
    if [[ -n "${options}" ]]; then
       # merge options from existing resolv.conf with specified resolv.conf content
       newres="${options}"$'\n'$(grep -vF "${options}" "${1}");
    else
       newres=$(cat "${1}");
    fi;

## Edited for yascker
    local new_resolv_conf
    new_resolv_conf=/etc/resolv.conf.dhclient-new
    rm -f $new_resolv_conf
    eval $(echo "${newres}" > $new_resolv_conf; echo "status=$?")

    chown --reference=/etc/resolv.conf $new_resolv_conf
    chmod --reference=/etc/resolv.conf $new_resolv_conf

    rm -f /etc/resolv.conf
    mv $new_resolv_conf /etc/resolv.conf
## Edited for yascker

    #Original line
    #eval $(echo "${newres}" > "${RESOLVCONF}"; echo "status=$?")
    if [[ $status -eq 0 ]]; then
        logger -p local7.notice -t "NET" -i "${0} : updated ${RESOLVCONF}";
        [[ -e /var/run/nscd/socket ]] && /usr/sbin/nscd -i hosts; # invalidate cache
    fi;
    return $status;
}**texto en negrita**

I still don’t understand why this permissions problem exists…