[samba] logon script и %G

Alexander Bokovoy ab на samba.org
Чт Ноя 10 13:07:50 MSK 2016


On to, 10 marras 2016, Gleb Kulikov wrote:
> В письме от 2016 November 10  (10:45:11) тов. Alexander Bokovoy написал:
> 
> > On to, 10 marras 2016, Gleb Kulikov wrote:
> > > Александр, добрый день!
> > > 
> > > А вот давно хотел спросить. Раньше была чудная опция
> > > -- logon script = %G.bat
> > > котора похоже. больше не работает. А что предлагается взамен?
> > 
> > Что значит "больше не работает"? В какой конфигурации?
> 
> стандартная конфигурация классического домен (в смысле NT) контроллера:
> 
> [global]
> 
>         security = user
> 	realm = SOME.TSU.RU
>         use kerberos keytab = Yes
>         SERVER ROLE = CLASSIC PRIMARY DOMAIN CONTROLLER
> 
>         passdb backend = ldapsam:ldap://127.0.0.1/
> 
>         ldap admin dn = cn=ldaproot,dc=some,dc=tsu,dc=ru
>         ldap suffix = dc=some,dc=tsu,dc=ru
>         ldap group suffix = ou=Group
>         ldap user suffix = ou=People
>         ldap ssl = off
> 	
> 	workgroup = SOME
> 	netbios name = KUKU
> 
> 	csc policy = disable
> 	local master = yes
> 	os level = 64
> 	domain master = yes
> 	preferred master = yes
> 
> 	domain logons = yes
> 
> 	logon path = \\%N\profiles\%u
>         logon drive = N:
> 
> 	logon script = %G.bat	# вариант %G исчез из документации и 
> действительно, НЕ РАБОТАЕТ: соотв. бат типа 
> /var/lib/samba/netlogon/students.bat на пльзовательской машине НЕ выполняется
Извини, из какой документации?

docs-xml/smbdotconf/logon/logonscript.xml содержит следующую отсылку:
        <para>
        This option takes the standard substitutions, allowing you to
        have separate logon scripts for each user or machine.
        </para>

стандартные подмены описаны в docs-xml/manpages/smb.conf.5.xml и там %G
присутствует в разделе VARIABLE SUBSTITUTIONS:
                <varlistentry>
                <term>%G</term>
                <listitem><para>primary group name of %U.</para></listitem>
                </varlistentry>


> 
> 	[netlogon]
>         	comment = Network Logon Service
>         	path = /var/lib/samba/netlogon
>         	guest ok = yes
>         	writable = no
>         	public = no
>         	browseable = yes
>         	share modes = no
> 
> ..................
> 
> 
> 
> > 
> > Насколько я вижу по коду, smbd в конфигурации классического контроллера
> > домена не изменился: если не используется LDAP, то используется logon script
> > из smb.conf. В случае использования 'passdb backend = ldapsam' используется
> > значение атрибута sambaLogonScript из LDAP или 'logon script' из
> > smb.conf при его отсутствии.
> 
> в LDAP logon script у меня не прописан.
> 
> Варианты per-user и per-machine РАБОТАЮТ, вариант per-GROUP НЕ работает и в 
> документации его больше нет.
В коде ldapsam всё предельно просто:
        logon_script = smbldap_talloc_single_attribute(
                        ldap_state->smbldap_state->ldap_struct,
                        entry,
                        get_userattr_key2string(ldap_state->schema_ver,
                                LDAP_ATTR_LOGON_SCRIPT),
                        ctx);
        if (logon_script) {
                if (expand_explicit) {
                        logon_script = talloc_sub_basic(ctx,
                                                username,
                                                domain,
                                                logon_script);
                        if (!logon_script) {
                                goto fn_exit;
                        }
                }
                pdb_set_logon_script(sampass, logon_script, PDB_SET);
        } else {
                pdb_set_logon_script(sampass,
                        talloc_sub_basic(ctx, username, domain,
                                         lp_logon_script()),
                        PDB_DEFAULT );
        }


То есть, значение logon script, полученное либо из LDAP, либо из
smb.conf, подвергается стандартным преобразованиям с одинаковыми
аргументами. В talloc_sub_basic() либо берется имя как есть, либо
квалифицируется доменом, затем через getpwnam() запрашиваются POSIX
атрибуты этого пользоваля и запрашивается имя его основной группы через
getgrgid(). Если мы в домене, то из полученного имени группы вырезается
домен. В результате, %G заменяется на имя группы.

                case 'G' : {
                        struct passwd *pass;
                        bool is_domain_name = false;
                        const char *sep = lp_winbind_separator();

                        if (domain_name != NULL && domain_name[0] != '\0' &&
                            (lp_security() == SEC_ADS ||
                             lp_security() == SEC_DOMAIN)) {
                                r = talloc_asprintf(tmp_ctx,
                                                    "%s%c%s",
                                                    domain_name,
                                                    *sep,
                                                    smb_name);
                                is_domain_name = true;
                        } else {
                                r = talloc_strdup(tmp_ctx, smb_name);
                        }
                        if (r == NULL) {
                                goto error;
                        }

                        pass = Get_Pwnam_alloc(tmp_ctx, r);
                        if (pass != NULL) {
                                char *group_name;

                                group_name = gidtoname(pass->pw_gid);
                                if (is_domain_name) {
                                        char *group_sep;
                                        group_sep = strchr_m(group_name, *sep);
                                        if (group_sep != NULL) {
                                                group_name = group_sep + 1;
                                        }
                                }
                                a_string = realloc_string_sub(a_string,
                                                              "%G",
                                                              group_name);
                        }
                        TALLOC_FREE(pass);
                        break;
                }

Таким образом, если %G не заменилось, то либо пользователь не виден в
getpwnam(), либо либо группа не видна через getgrgid().

-- 
/ Alexander Bokovoy


Подробная информация о списке рассылки Samba