В связи с такой необходимостью решил воспользоваться готовым скриптом migrate_passwd.pl из пакета migration tools. Полученный лдиф файл меня всем устроил, кроме строки с паролем. У всех пользователей там, где должен быть хеш пароля везде одинаковая строка типа {crypt}x
Разумеется ничего общего это с реальными паролями не имеет. Такое ощущение, что скрипт не обрабатывает /etc/shadow или делает это как то не так. Почему и как исправить?
перевод локальных учеток в базу лдап (пакет migration_tools)
Модератор: /dev/random
Re: перевод локальных учеток в базу лдап
Может это специфика дистрибутива? По-прежнему непонятно.
вот migrate_passwd.pl
А это сопутствующий migrate_common.ph
вот migrate_passwd.pl
Код: Выделить всё
#!/usr/bin/perl
#
# $Id: migrate_passwd.pl,v 1.17 2005/03/05 03:15:55 lukeh Exp $
#
# Copyright (c) 1997-2003 Luke Howard.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by Luke Howard.
# 4. The name of the other may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE LUKE HOWARD ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL LUKE HOWARD BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# Password migration tool. Migrates /etc/shadow as well, if it exists.
#
# Thanks to Peter Jacob Slot <peter@vision.auk.dk>.
#
require 'migrate_common.ph';
$PROGRAM = "migrate_passwd.pl";
$NAMINGCONTEXT = &getsuffix($PROGRAM);
&parse_args();
&read_shadow_file();
&open_files();
while(<INFILE>)
{
chop;
next if /^\s*$/;
next if /^#/;
next if /^\+/;
s/�/Ae/g;
s/�/Ee/g;
s/�/Ie/g;
s/�/Oe/g;
s/�/Ue/g;
s/�/ae/g;
s/�/ee/g;
s/�/ie/g;
s/�/oe/g;
s/�/ue/g;
s/�/ye/g;
s/�/ss/g;
s/�/e/g;
s/�/Ae/g;
s/�/ae/g;
s/�/Oe/g;
s/�/oe/g;
s/�/Ae/g;
s/�/ae/g;
local($user, $pwd, $uid, $gid, $gecos, $homedir, $shell) = split(/:/);
if ($use_stdout) {
&dump_user(STDOUT, $user, $pwd, $uid, $gid, $gecos, $homedir, $shell);
} else {
&dump_user(OUTFILE, $user, $pwd, $uid, $gid, $gecos, $homedir, $shell);
}
}
sub dump_user
{
local($HANDLE, $user, $pwd, $uid, $gid, $gecos, $homedir, $shell) = @_;
local($name,$office,$wphone,$hphone)=split(/,/,$gecos);
local($sn);
local($givenname);
local($cn);
local(@tmp);
if ($name) { $cn = $name; } else { $cn = $user; }
$_ = $cn;
@tmp = split(/\s+/);
$sn = $tmp[$#tmp];
pop(@tmp);
$givenname=join(' ',@tmp);
print $HANDLE "dn: uid=$user,$NAMINGCONTEXT\n";
print $HANDLE "uid: $user\n";
print $HANDLE "cn: $cn\n";
if ($EXTENDED_SCHEMA) {
if ($wphone) {
print $HANDLE "telephoneNumber: $wphone\n";
}
if ($office) {
print $HANDLE "roomNumber: $office\n";
}
if ($hphone) {
print $HANDLE "homePhone: $hphone\n";
}
if ($givenname) {
print $HANDLE "givenName: $givenname\n";
}
print $HANDLE "sn: $sn\n";
if ($DEFAULT_MAIL_DOMAIN) {
print $HANDLE "mail: $user\@$DEFAULT_MAIL_DOMAIN\n";
}
if ($DEFAULT_MAIL_HOST) {
print $HANDLE "mailRoutingAddress: $user\@$DEFAULT_MAIL_HOST\n";
print $HANDLE "mailHost: $DEFAULT_MAIL_HOST\n";
print $HANDLE "objectClass: inetLocalMailRecipient\n";
}
print $HANDLE "objectClass: person\n";
print $HANDLE "objectClass: organizationalPerson\n";
print $HANDLE "objectClass: inetOrgPerson\n";
} else {
print $HANDLE "objectClass: account\n";
}
print $HANDLE "objectClass: posixAccount\n";
print $HANDLE "objectClass: top\n";
if ($DEFAULT_REALM) {
print $HANDLE "objectClass: kerberosSecurityObject\n";
}
if ($shadowUsers{$user} ne "") {
&dump_shadow_attributes($HANDLE, split(/:/, $shadowUsers{$user}));
} else {
print $HANDLE "userPassword: {crypt}$pwd\n";
}
if ($DEFAULT_REALM) {
print $HANDLE "krbName: $user\@$DEFAULT_REALM\n";
}
if ($shell) {
print $HANDLE "loginShell: $shell\n";
}
if ($uid ne "") {
print $HANDLE "uidNumber: $uid\n";
} else {
print $HANDLE "uidNumber:\n";
}
if ($gid ne "") {
print $HANDLE "gidNumber: $gid\n";
} else {
print $HANDLE "gidNumber:\n";
}
if ($homedir) {
print $HANDLE "homeDirectory: $homedir\n";
} else {
print $HANDLE "homeDirectory:\n";
}
if ($gecos) {
print $HANDLE "gecos: $gecos\n";
}
print $HANDLE "\n";
}
close(INFILE);
if (OUTFILE != STDOUT) { close(OUTFILE); }
sub read_shadow_file
{
open(SHADOW, "/etc/shadow") || return;
while(<SHADOW>) {
chop;
($shadowUser) = split(/:/, $_);
$shadowUsers{$shadowUser} = $_;
}
close(SHADOW);
}
sub dump_shadow_attributes
{
local($HANDLE, $user, $pwd, $lastchg, $min, $max, $warn, $inactive, $expire, $flag) = @_;
print $HANDLE "objectClass: shadowAccount\n";
if ($pwd) {
print $HANDLE "userPassword: {crypt}$pwd\n";
}
if ($lastchg ne "") {
print $HANDLE "shadowLastChange: $lastchg\n";
}
if ($min) {
print $HANDLE "shadowMin: $min\n";
}
if ($max) {
print $HANDLE "shadowMax: $max\n";
}
if ($warn) {
print $HANDLE "shadowWarning: $warn\n";
}
if ($inactive) {
print $HANDLE "shadowInactive: $inactive\n";
}
if ($expire) {
print $HANDLE "shadowExpire: $expire\n";
}
if ($flag) {
print $HANDLE "shadowFlag: $flag\n";
}
}
А это сопутствующий migrate_common.ph
Код: Выделить всё
#
# $Id: migrate_common.ph,v 1.22 2003/04/15 03:09:33 lukeh Exp $
#
# Copyright (c) 1997-2003 Luke Howard.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by Luke Howard.
# 4. The name of the other may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE LUKE HOWARD ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL LUKE HOWARD BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#
# Common defines for MigrationTools
#
# Naming contexts. Key is $PROGRAM with migrate_ and .pl
# stripped off.
$NETINFOBRIDGE = (-x "/usr/sbin/mkslapdconf");
if ($NETINFOBRIDGE) {
$NAMINGCONTEXT{'aliases'} = "cn=aliases";
$NAMINGCONTEXT{'fstab'} = "cn=mounts";
$NAMINGCONTEXT{'passwd'} = "cn=users";
$NAMINGCONTEXT{'netgroup_byuser'} = "cn=netgroup.byuser";
$NAMINGCONTEXT{'netgroup_byhost'} = "cn=netgroup.byhost";
$NAMINGCONTEXT{'group'} = "cn=groups";
$NAMINGCONTEXT{'netgroup'} = "cn=netgroup";
$NAMINGCONTEXT{'hosts'} = "cn=machines";
$NAMINGCONTEXT{'networks'} = "cn=networks";
$NAMINGCONTEXT{'protocols'} = "cn=protocols";
$NAMINGCONTEXT{'rpc'} = "cn=rpcs";
$NAMINGCONTEXT{'services'} = "cn=services";
} else {
$NAMINGCONTEXT{'aliases'} = "ou=Aliases";
$NAMINGCONTEXT{'fstab'} = "ou=Mounts";
$NAMINGCONTEXT{'passwd'} = "ou=People";
$NAMINGCONTEXT{'netgroup_byuser'} = "nisMapName=netgroup.byuser";
$NAMINGCONTEXT{'netgroup_byhost'} = "nisMapName=netgroup.byhost";
$NAMINGCONTEXT{'group'} = "ou=Group";
$NAMINGCONTEXT{'netgroup'} = "ou=Netgroup";
$NAMINGCONTEXT{'hosts'} = "ou=Hosts";
$NAMINGCONTEXT{'networks'} = "ou=Networks";
$NAMINGCONTEXT{'protocols'} = "ou=Protocols";
$NAMINGCONTEXT{'rpc'} = "ou=Rpc";
$NAMINGCONTEXT{'services'} = "ou=Services";
}
# Default DNS domain
$DEFAULT_MAIL_DOMAIN = "linux.org";
# Default base
$DEFAULT_BASE = "dc=linux,dc=org";
# Turn this on for inetLocalMailReceipient
# sendmail support; add the following to
# sendmail.mc (thanks to Petr@Kristof.CZ):
##### CUT HERE #####
#define(`confLDAP_DEFAULT_SPEC',`-h "ldap.padl.com"')dnl
#LDAPROUTE_DOMAIN_FILE(`/etc/mail/ldapdomains')dnl
#FEATURE(ldap_routing)dnl
##### CUT HERE #####
# where /etc/mail/ldapdomains contains names of ldap_routed
# domains (similiar to MASQUERADE_DOMAIN_FILE).
$DEFAULT_MAIL_HOST = "mail.padl.com";
# turn this on to support more general object clases
# such as person.
$EXTENDED_SCHEMA = 0;
#
# allow environment variables to override predefines
#
if (defined($ENV{'LDAP_BASEDN'})) {
$DEFAULT_BASE = $ENV{'LDAP_BASEDN'};
}
if (defined($ENV{'LDAP_DEFAULT_MAIL_DOMAIN'})) {
$DEFAULT_MAIL_DOMAIN = $ENV{'LDAP_DEFAULT_MAIL_DOMAIN'};
}
if (defined($ENV{'LDAP_DEFAULT_MAIL_HOST'})) {
$DEFAULT_MAIL_HOST = $ENV{'LDAP_DEFAULT_MAIL_HOST'};
}
# binddn used for alias owner (otherwise uid=root,...)
if (defined($ENV{'LDAP_BINDDN'})) {
$DEFAULT_OWNER = $ENV{'LDAP_BINDDN'};
}
if (defined($ENV{'LDAP_EXTENDED_SCHEMA'})) {
$EXTENDED_SCHEMA = $ENV{'LDAP_EXTENDED_SCHEMA'};
}
# If we haven't set the default base, guess it automagically.
if (!defined($DEFAULT_BASE)) {
$DEFAULT_BASE = &domain_expand($DEFAULT_MAIL_DOMAIN);
$DEFAULT_BASE =~ s/,$//o;
}
# Default Kerberos realm
if ($EXTENDED_SCHEMA) {
$DEFAULT_REALM = $DEFAULT_MAIL_DOMAIN;
$DEFAULT_REALM =~ tr/a-z/A-Z/;
}
if (-x "/usr/sbin/revnetgroup") {
$REVNETGROUP = "/usr/sbin/revnetgroup";
} elsif (-x "/usr/lib/yp/revnetgroup") {
$REVNETGROUP = "/usr/lib/yp/revnetgroup";
}
$classmap{'o'} = 'organization';
$classmap{'dc'} = 'domain';
$classmap{'l'} = 'locality';
$classmap{'ou'} = 'organizationalUnit';
$classmap{'c'} = 'country';
$classmap{'nismapname'} = 'nisMap';
$classmap{'cn'} = 'container';
sub parse_args
{
if ($#ARGV < 0) {
print STDERR "Usage: $PROGRAM infile [outfile]\n";
exit 1;
}
$INFILE = $ARGV[0];
if ($#ARGV > 0) {
$OUTFILE = $ARGV[1];
}
}
sub open_files
{
open(INFILE);
if ($OUTFILE) {
open(OUTFILE,">$OUTFILE");
$use_stdout = 0;
} else {
$use_stdout = 1;
}
}
# moved from migrate_hosts.pl
# lukeh 10/30/97
sub domain_expand
{
local($first) = 1;
local($dn);
local(@namecomponents) = split(/\./, $_[0]);
foreach $_ (@namecomponents) {
$first = 0;
$dn .= "dc=$_,";
}
$dn .= $DEFAULT_BASE;
return $dn;
}
# case insensitive unique
sub uniq
{
local($name) = shift(@_);
local(@vec) = sort {uc($a) cmp uc($b)} @_;
local(@ret);
local($next, $last);
foreach $next (@vec) {
if ((uc($next) ne uc($last)) &&
(uc($next) ne uc($name))) {
push (@ret, $next);
}
$last = $next;
}
return @ret;
}
# concatenate naming context and
# organizational base
sub getsuffix
{
local($program) = shift(@_);
local($nc);
$program =~ s/^migrate_(.*)\.pl$/$1/;
$nc = $NAMINGCONTEXT{$program};
if ($nc eq "") {
return $DEFAULT_BASE;
} else {
return $nc . ',' . $DEFAULT_BASE;
}
}
sub ldif_entry
{
# remove leading, trailing whitespace
local ($HANDLE, $lhs, $rhs) = @_;
local ($type, $val) = split(/\=/, $lhs);
local ($dn);
if ($rhs ne "") {
$dn = $lhs . ',' . $rhs;
} else {
$dn = $lhs;
}
$type =~ s/\s*$//o;
$type =~ s/^\s*//o;
$type =~ tr/A-Z/a-z/;
$val =~ s/\s*$//o;
$val =~ s/^\s*//o;
print $HANDLE "dn: $dn\n";
print $HANDLE "$type: $val\n";
print $HANDLE "objectClass: top\n";
print $HANDLE "objectClass: $classmap{$type}\n";
if ($EXTENDED_SCHEMA) {
if ($DEFAULT_MAIL_DOMAIN) {
print $HANDLE "objectClass: domainRelatedObject\n";
print $HANDLE "associatedDomain: $DEFAULT_MAIL_DOMAIN\n";
}
}
print $HANDLE "\n";
}
# Added Thu Jun 20 16:40:28 CDT 2002 by Bob Apthorpe
# <apthorpe@cynistar.net> to solve problems with embedded plusses in
# protocols and mail aliases.
sub escape_metacharacters
{
local($name) = @_;
# From Table 3.1 "Characters Requiring Quoting When Contained
# in Distinguished Names", p87 "Understanding and Deploying LDAP
# Directory Services", Howes, Smith, & Good.
# 1) Quote backslash
# Note: none of these are very elegant or robust and may cause
# more trouble than they're worth. That's why they're disabled.
# 1.a) naive (escape all backslashes)
# $name =~ s#\\#\\\\#og;
#
# 1.b) mostly naive (escape all backslashes not followed by
# a backslash)
# $name =~ s#\\(?!\\)#\\\\#og;
#
# 1.c) less naive and utterly gruesome (replace solitary
# backslashes)
# $name =~ s{ # Replace
# (?<!\\) # negative lookbehind (no preceding backslash)
# \\ # a single backslash
# (?!\\) # negative lookahead (no following backslash)
# }
# { # With
# \\\\ # a pair of backslashes
# }gx;
# Ugh. Note that s#(?:[^\\])\\(?:[^\\])#////#g fails if $name
# starts or ends with a backslash. This expression won't work
# under perl4 because the /x flag and negative lookahead and
# lookbehind operations aren't supported. Sorry. Also note that
# s#(?:[^\\]*)\\(?:[^\\]*)#////#g won't work either. Of course,
# this is all broken if $name is already escaped before we get
# to it. Best to throw a warning and make the user import these
# records by hand.
# 2) Quote leading and trailing spaces
local($leader, $body, $trailer) = ();
if (($leader, $body, $trailer) = ($name =~ m#^( *)(.*\S)( *)$#o)) {
$leader =~ s# #\\ #og;
$trailer =~ s# #\\ #og;
$name = $leader . $body . $trailer;
}
# 3) Quote leading octothorpe (#)
$name =~ s/^#/\\#/o;
# 4) Quote comma, plus, double-quote, less-than, greater-than,
# and semicolon
$name =~ s#([,+"<>;])#\\$1#g;
return $name;
}
1;
Re: перевод локальных учеток в базу лдап
ska писал(а): ↑09.02.2011 17:43В связи с такой необходимостью решил воспользоваться готовым скриптом migrate_passwd.pl из пакета migration tools. Полученный лдиф файл меня всем устроил, кроме строки с паролем. У всех пользователей там, где должен быть хеш пароля везде одинаковая строка типа {crypt}x
Разумеется ничего общего это с реальными паролями не имеет. Такое ощущение, что скрипт не обрабатывает /etc/shadow или делает это как то не так. Почему и как исправить?
я предлагаю проверить на паре пользователей схемку с принудительной установкой пароля через консоль... тут еще могут быть проблемы с конфигами.
Re: перевод локальных учеток в базу лдап
patrius писал(а): ↑11.02.2011 23:01ska писал(а): ↑09.02.2011 17:43В связи с такой необходимостью решил воспользоваться готовым скриптом migrate_passwd.pl из пакета migration tools. Полученный лдиф файл меня всем устроил, кроме строки с паролем. У всех пользователей там, где должен быть хеш пароля везде одинаковая строка типа {crypt}x
Разумеется ничего общего это с реальными паролями не имеет. Такое ощущение, что скрипт не обрабатывает /etc/shadow или делает это как то не так. Почему и как исправить?
я предлагаю проверить на паре пользователей схемку с принудительной установкой пароля через консоль... тут еще могут быть проблемы с конфигами.
Не знаю, правильно ли я вас понял, но я прикрутил например к сквиду авторизацию через лдап базу. И она вполне себе работает. Но мне не хочется вручную вводить пароли для всех записей. Хотелось бы с помощью этого скрипта.
Установка пароля через консоль это как?
- /dev/random
- Администратор
- Сообщения: 5289
- ОС: Gentoo
Re: перевод локальных учеток в базу лдап
Бегло просмотрел скрипт. На первый взгляд, вижу только один случай, в котором может возникнуть строка "{crypt}x": если не удаётся открыть /etc/shadow. Вы точно от рута его запускали?
Re: перевод локальных учеток в базу лдап
ska писал(а): ↑12.02.2011 07:38patrius писал(а): ↑11.02.2011 23:01ska писал(а): ↑09.02.2011 17:43В связи с такой необходимостью решил воспользоваться готовым скриптом migrate_passwd.pl из пакета migration tools. Полученный лдиф файл меня всем устроил, кроме строки с паролем. У всех пользователей там, где должен быть хеш пароля везде одинаковая строка типа {crypt}x
Разумеется ничего общего это с реальными паролями не имеет. Такое ощущение, что скрипт не обрабатывает /etc/shadow или делает это как то не так. Почему и как исправить?
я предлагаю проверить на паре пользователей схемку с принудительной установкой пароля через консоль... тут еще могут быть проблемы с конфигами.
Не знаю, правильно ли я вас понял, но я прикрутил например к сквиду авторизацию через лдап базу. И она вполне себе работает. Но мне не хочется вручную вводить пароли для всех записей. Хотелось бы с помощью этого скрипта.
Установка пароля через консоль это как?
из чего следует, что все интереснее....
когда вы собирались переносить пользователей в LDAP, вы ж выбрали инструментарий для дальнейшего сопровождения?
вот им и воспользуйтесь.
/dev/random писал(а): ↑12.02.2011 07:45Бегло просмотрел скрипт. На первый взгляд, вижу только один случай, в котором может возникнуть строка "{crypt}x": если не удаётся открыть /etc/shadow. Вы точно от рута его запускали?
кстати, да... присоединяюсь к вопросу.
Re: перевод локальных учеток в базу лдап
/dev/random писал(а): ↑12.02.2011 07:45Бегло просмотрел скрипт. На первый взгляд, вижу только один случай, в котором может возникнуть строка "{crypt}x": если не удаётся открыть /etc/shadow. Вы точно от рута его запускали?
да точно вот так делаю
Код: Выделить всё
[root@linux MigrationTools-47]# ./migrate_passwd.pl /etc/passwd /home/linux/passwd2.ldif
В итоге получаю такой файл (вот пользователь pupil напримаер)
Код: Выделить всё
[root@linux MigrationTools-47]# cat /home/linux/passwd2.ldif
dn: uid=pupil,ou=People,dc=linux,dc=org
uid: pupil
cn: Все ученики
objectClass: account
objectClass: posixAccount
objectClass: top
userPassword: {crypt}x
loginShell: /bin/bash
uidNumber: 501
gidNumber: 501
homeDirectory: /home/pupil
gecos: Все ученики
Строка с паролем выглядит так же как и в /etc/passwd
Код: Выделить всё
pupil:x:501:501:Все ученики:/home/pupil:/bin/bash
когда вы собирались переносить пользователей в LDAP, вы ж выбрали инструментарий для дальнейшего сопровождения?
вот им и воспользуйтесь.
Началось все с чтений всяких инструкций по настройке лдап. Почти во всех из них говорится про этот скрипт. Вот я и решил им пользоваться, потому что про другие ничего не знаю(.
Re: перевод локальных учеток в базу лдап
1, проверьте внимательно соответствие на нескольких пользователях с паролями различной сложности.
2.
- 1! определение задач
- 2! выбор инструментария
- 3! заполнение информацией
В зависимости от "1!" инструменты могут быть различны. Подумайте о сложившейся ситуации.
И только после этого читайте информацию, например, тут.
2.
Началось все с чтений всяких инструкций по настройке лдап. Почти во всех из них говорится про этот скрипт. Вот я и решил им пользоваться, потому что про другие ничего не знаю(.
- 1! определение задач
- 2! выбор инструментария
- 3! заполнение информацией
В зависимости от "1!" инструменты могут быть различны. Подумайте о сложившейся ситуации.
И только после этого читайте информацию, например, тут.