2005-08-28 22:17:07 +00:00
/ *
backend code for upgrading from Samba3
Copyright Jelmer Vernooij 2005
Released under the GNU GPL v2 or later
* /
2005-08-28 23:03:49 +00:00
libinclude ( "base.js" ) ;
2005-08-28 22:17:07 +00:00
2005-08-29 12:31:32 +00:00
function regkey _to _dn ( name )
2005-08-28 23:03:49 +00:00
{
2005-08-29 12:31:32 +00:00
var dn = "hive=NONE" ;
var i = 0 ;
2005-08-28 23:03:49 +00:00
2005-08-29 12:31:32 +00:00
var as = split ( "/" , name ) ;
for ( i in as ) {
if ( i > 0 ) {
dn = sprintf ( "key=%s," , as [ i ] ) + dn ;
}
}
return dn ;
}
/ * W h e r e p r e f i x i s a n y o f :
* - HKLM
* HKU
* HKCR
* HKPD
* HKPT
* /
2005-08-31 15:46:41 +00:00
function upgrade _registry ( regdb , prefix , ldb )
2005-08-29 12:31:32 +00:00
{
2005-08-29 18:52:24 +00:00
assert ( regdb != undefined ) ;
2005-08-29 12:31:32 +00:00
var prefix _up = strupper ( prefix ) ;
2005-08-30 12:27:53 +00:00
var ldif = new Array ( ) ;
2005-08-29 12:31:32 +00:00
for ( var i in regdb . keys ) {
var rk = regdb . keys [ i ] ;
2005-08-29 18:52:24 +00:00
var pts = split ( "/" , rk . name ) ;
2005-08-29 12:31:32 +00:00
/* Only handle selected hive */
2005-08-29 18:52:24 +00:00
if ( strupper ( pts [ 0 ] ) != prefix _up ) {
2005-08-29 12:31:32 +00:00
continue ;
}
var keydn = regkey _to _dn ( rk . name ) ;
var pts = split ( "/" , rk . name ) ;
/* Convert key name to dn */
2005-08-30 12:27:53 +00:00
ldif [ rk . name ] = sprintf ( "
2005-08-29 12:31:32 +00:00
dn : % s
name : % s
" , keydn , pts [ 0 ] ) ;
for ( var j in rk . values ) {
var rv = rk . values [ j ] ;
2005-08-30 12:27:53 +00:00
ldif [ rk . name + " (" + rv . name + ")" ] = sprintf ( "
2005-08-29 12:31:32 +00:00
dn : % s , value = % s
value : % s
type : % d
2005-08-31 15:46:41 +00:00
data : : % s " , keydn , rv . name , rv . name , rv . type , ldb . encode ( rv . data ) ) ;
2005-08-29 12:31:32 +00:00
}
}
return ldif ;
}
2005-08-29 15:54:10 +00:00
function upgrade _sam _policy ( samba3 , dn )
2005-08-29 12:31:32 +00:00
{
var ldif = sprintf ( "
dn : % s
2005-08-29 18:52:24 +00:00
changetype : modify
replace : minPwdLength
2005-08-29 12:31:32 +00:00
minPwdLength : % d
pwdHistoryLength : % d
minPwdAge : % d
maxPwdAge : % d
lockoutDuration : % d
samba3ResetCountMinutes : % d
samba3UserMustLogonToChangePassword : % d
samba3BadLockoutMinutes : % d
samba3DisconnectTime : % d
samba3RefuseMachinePwdChange : % d
2005-08-29 15:54:10 +00:00
" , dn , samba3 . policy . min _password _length ,
2005-08-29 12:31:32 +00:00
samba3 . policy . password _history , samba3 . policy . minimum _password _age ,
samba3 . policy . maximum _password _age , samba3 . policy . lockout _duration ,
samba3 . policy . reset _count _minutes , samba3 . policy . user _must _logon _to _change _password ,
samba3 . policy . bad _lockout _minutes , samba3 . policy . disconnect _time ,
samba3 . policy . refuse _machine _password _change
) ;
2005-09-01 00:37:52 +00:00
2005-08-29 12:31:32 +00:00
return ldif ;
}
2005-09-01 00:37:52 +00:00
function upgrade _sam _account ( ldb , acc , domaindn , domainsid )
2005-08-29 12:31:32 +00:00
{
2005-09-01 00:37:52 +00:00
if ( acc . nt _username == undefined ) {
acc . nt _username = acc . username ;
}
if ( acc . nt _username == "" ) {
acc . nt _username = acc . username ;
}
if ( acc . fullname == undefined ) {
var pw = nss . getpwnam ( acc . fullname ) ;
acc . fullname = pw . pw _gecos ;
}
var pts = split ( ',' , acc . fullname ) ;
acc . fullname = pts [ 0 ] ;
assert ( acc . fullname != undefined ) ;
assert ( acc . nt _username != undefined ) ;
2005-08-29 12:31:32 +00:00
var ldif = sprintf (
" dn : cn = % s , % s
2005-09-01 00:37:52 +00:00
objectClass : top
2005-08-29 12:31:32 +00:00
objectClass : user
lastLogon : % d
lastLogoff : % d
unixName : % s
name : % s
2005-09-01 00:37:52 +00:00
sAMAccountName : % s
2005-08-29 12:31:32 +00:00
cn : % s
description : % s
primaryGroupID : % d
badPwdcount : % d
logonCount : % d
samba3Domain : % s
samba3DirDrive : % s
samba3MungedDial : % s
samba3Homedir : % s
samba3LogonScript : % s
samba3ProfilePath : % s
samba3Workstations : % s
samba3KickOffTime : % d
samba3BadPwdTime : % d
samba3PassLastSetTime : % d
samba3PassCanChangeTime : % d
samba3PassMustChangeTime : % d
2005-09-01 00:37:52 +00:00
objectSid : % s - % d
2005-08-30 00:41:02 +00:00
ntPwdHash : : % s
lmPwdHash : : % s
2005-08-29 12:31:32 +00:00
2005-09-01 00:37:52 +00:00
" , acc . fullname , domaindn , acc . logon _time , acc . logoff _time , acc . username , acc . nt _username , acc . nt _username ,
2005-08-29 12:31:32 +00:00
acc . fullname , acc . acct _desc , acc . group _rid , acc . bad _password _count , acc . logon _count ,
acc . domain , acc . dir _drive , acc . munged _dial , acc . homedir , acc . logon _script ,
acc . profile _path , acc . workstations , acc . kickoff _time , acc . bad _password _time ,
2005-09-01 00:37:52 +00:00
acc . pass _last _set _time , acc . pass _can _change _time , acc . pass _must _change _time , domainsid , acc . user _rid ,
2005-08-29 22:01:18 +00:00
ldb . encode ( acc . lm _pw ) , ldb . encode ( acc . nt _pw ) ) ;
2005-08-29 12:31:32 +00:00
return ldif ;
}
function upgrade _sam _group ( grp , domaindn )
{
2005-09-01 00:37:52 +00:00
var nss = nss _init ( ) ;
var gr ;
if ( grp . sid _name _use == 5 ) { // Well-known group
return undefined ;
}
if ( grp . nt _name == "Domain Guests" ||
grp . nt _name == "Domain Users" ||
grp . nt _name == "Domain Admins" ) {
return undefined ;
}
if ( grp . gid == - 1 ) {
gr = nss . getgrnam ( grp . nt _name ) ;
} else {
gr = nss . getgrgid ( grp . gid ) ;
}
if ( gr == undefined ) {
grp . unixname = "UNKNOWN" ;
} else {
grp . unixname = gr . gr _name ;
}
assert ( grp . unixname != undefined ) ;
2005-08-29 12:31:32 +00:00
var ldif = sprintf (
" dn : cn = % s , % s
objectClass : top
objectClass : group
description : % s
cn : % s
objectSid : % s
2005-09-01 00:37:52 +00:00
unixName : % s
2005-08-29 18:52:24 +00:00
samba3SidNameUse : % d
" , grp . nt _name , domaindn ,
2005-09-01 00:37:52 +00:00
grp . comment , grp . nt _name , grp . sid , grp . unixname , grp . sid _name _use ) ;
2005-08-29 12:31:32 +00:00
return ldif ;
}
function upgrade _winbind ( samba3 , domaindn )
{
var ldif = sprintf ( "
dn : dc = none
userHwm : % d
groupHwm : % d
" , samba3 . idmap . user _hwm , samba3 . idmap . group _hwm ) ;
for ( var i in samba3 . idmap . mappings ) {
var m = samba3 . idmap . mappings [ i ] ;
ldif = ldif + sprintf ( "
dn : SID = % s , % s
SID : % s
type : % d
unixID : % d " , m . sid , domaindn , m . sid , m . type , m . unix _id ) ;
}
return ldif ;
}
* /
function upgrade _wins ( samba3 )
{
var ldif = "" ;
for ( i in samba3 . winsentries ) {
var e = samba3 . winsentries [ i ] ;
ldif = ldif + sprintf ( "
dn : type = % d , name = % s
name : % s
objectClass : wins
nbFlags : % x
2005-08-29 18:52:24 +00:00
expires : % s
" , e . type , e . name , e . name , e . type , e . nb _flags , sys . ldaptime ( e . ttl ) ) ;
2005-08-29 12:31:32 +00:00
for ( var i in e . ips ) {
ldif = ldif + sprintf ( "address: %s\n" , e . ips [ i ] ) ;
}
}
return ldif ;
}
function upgrade _provision ( samba3 )
{
var subobj = new Object ( ) ;
var nss = nss _init ( ) ;
var lp = loadparm _init ( ) ;
var rdn _list ;
2005-08-30 14:44:33 +00:00
var domainname = samba3 . configuration . get ( "workgroup" ) ;
2005-08-29 18:52:24 +00:00
if ( domainname == undefined ) {
domainname = samba3 . secrets . domains [ 0 ] . name ;
println ( "No domain specified in smb.conf file, assuming '" + domainname + "'" ) ;
}
2005-08-29 12:31:32 +00:00
var domsec = samba3 . find _domainsecrets ( domainname ) ;
var hostsec = samba3 . find _domainsecrets ( hostname ( ) ) ;
2005-08-30 14:44:33 +00:00
var realm = samba3 . configuration . get ( "realm" ) ;
2005-08-29 18:52:24 +00:00
if ( realm == undefined ) {
realm = domainname ;
println ( "No realm specified in smb.conf file, assuming '" + realm + "'" ) ;
}
2005-08-29 12:31:32 +00:00
random _init ( local ) ;
subobj . REALM = realm ;
subobj . DOMAIN = domainname ;
subobj . HOSTNAME = hostname ( ) ;
assert ( subobj . REALM ) ;
assert ( subobj . DOMAIN ) ;
assert ( subobj . HOSTNAME ) ;
subobj . HOSTIP = hostip ( ) ;
2005-08-29 18:52:24 +00:00
if ( domsec != undefined ) {
subobj . DOMAINGUID = domsec . guid ;
subobj . DOMAINSID = domsec . sid ;
} else {
println ( "Can't find domain secrets for '" + domainname + "'; using random SID and GUID" ) ;
subobj . DOMAINGUID = randguid ( ) ;
2005-08-29 20:18:51 +00:00
subobj . DOMAINSID = randsid ( ) ;
2005-08-29 18:52:24 +00:00
}
if ( hostsec ) {
subobj . HOSTGUID = hostsec . guid ;
} else {
subobj . HOSTGUID = randguid ( ) ;
}
2005-08-29 12:31:32 +00:00
subobj . INVOCATIONID = randguid ( ) ;
subobj . KRBTGTPASS = randpass ( 12 ) ;
subobj . MACHINEPASS = randpass ( 12 ) ;
subobj . ADMINPASS = randpass ( 12 ) ;
subobj . DEFAULTSITE = "Default-First-Site-Name" ;
subobj . NEWGUID = randguid ;
subobj . NTTIME = nttime ;
subobj . LDAPTIME = ldaptime ;
subobj . DATESTRING = datestring ;
subobj . USN = nextusn ;
2005-08-29 18:52:24 +00:00
subobj . ROOT = findnss ( nss . getpwnam , "root" ) ;
2005-08-29 12:31:32 +00:00
subobj . NOBODY = findnss ( nss . getpwnam , "nobody" ) ;
subobj . NOGROUP = findnss ( nss . getgrnam , "nogroup" , "nobody" ) ;
subobj . WHEEL = findnss ( nss . getgrnam , "wheel" , "root" ) ;
subobj . USERS = findnss ( nss . getgrnam , "users" , "guest" , "other" ) ;
subobj . DNSDOMAIN = strlower ( subobj . REALM ) ;
subobj . DNSNAME = sprintf ( "%s.%s" ,
strlower ( subobj . HOSTNAME ) ,
subobj . DNSDOMAIN ) ;
subobj . BASEDN = "DC=" + join ( ",DC=" , split ( "." , subobj . REALM ) ) ;
rdn _list = split ( "." , subobj . REALM ) ;
return subobj ;
2005-08-28 23:03:49 +00:00
}
2005-08-29 15:54:10 +00:00
2005-08-30 16:09:38 +00:00
smbconf _keep = new Array (
2005-08-29 15:54:10 +00:00
"dos charset" ,
"unix charset" ,
"display charset" ,
"comment" ,
"path" ,
"directory" ,
"workgroup" ,
"realm" ,
"netbios name" ,
"netbios aliases" ,
"netbios scope" ,
"server string" ,
"interfaces" ,
"bind interfaces only" ,
"security" ,
"auth methods" ,
"encrypt passwords" ,
"null passwords" ,
"obey pam restrictions" ,
"password server" ,
"smb passwd file" ,
"private dir" ,
"passwd chat" ,
"password level" ,
"lanman auth" ,
"ntlm auth" ,
"client NTLMv2 auth" ,
"client lanman auth" ,
"client plaintext auth" ,
"read only" ,
"hosts allow" ,
"hosts deny" ,
"log level" ,
"debuglevel" ,
"log file" ,
"smb ports" ,
"large readwrite" ,
"max protocol" ,
"min protocol" ,
"unicode" ,
"read raw" ,
"write raw" ,
"disable netbios" ,
"nt status support" ,
"announce version" ,
"announce as" ,
"max mux" ,
"max xmit" ,
"name resolve order" ,
"max wins ttl" ,
"min wins ttl" ,
"time server" ,
"unix extensions" ,
"use spnego" ,
"server signing" ,
"client signing" ,
"max connections" ,
"paranoid server security" ,
"socket options" ,
"strict sync" ,
"max print jobs" ,
"printable" ,
"print ok" ,
"printer name" ,
"printer" ,
"map system" ,
"map hidden" ,
"map archive" ,
"domain logons" ,
"preferred master" ,
"prefered master" ,
"local master" ,
"domain master" ,
"browseable" ,
"browsable" ,
"wins server" ,
"wins support" ,
"csc policy" ,
"strict locking" ,
"config file" ,
"preload" ,
"auto services" ,
"lock dir" ,
"lock directory" ,
"pid directory" ,
"socket address" ,
"copy" ,
"include" ,
"available" ,
"volume" ,
"fstype" ,
"panic action" ,
"msdfs root" ,
"host msdfs" ,
"winbind separator" ) ;
2005-08-30 16:09:38 +00:00
/ *
Remove configuration variables not present in Samba4
oldconf : Old configuration structure
mark : Whether removed configuration variables should be
kept in the new configuration as "samba3:<name>"
* /
function upgrade _smbconf ( oldconf , mark )
2005-08-29 15:54:10 +00:00
{
2005-08-30 16:09:38 +00:00
var data = oldconf . data ( ) ;
var newconf = param _init ( ) ;
for ( var s in data ) {
for ( var p in data [ s ] ) {
var keep = false ;
for ( var k in smbconf _keep ) {
if ( smbconf _keep [ k ] == p ) {
keep = true ;
break ;
}
}
2005-08-29 18:52:24 +00:00
2005-08-30 16:09:38 +00:00
if ( keep ) {
newconf . set ( s , p , oldconf . get ( s , p ) ) ;
} else if ( mark ) {
newconf . set ( s , "samba3:" + p , oldconf . get ( s , p ) ) ;
}
2005-08-29 22:01:18 +00:00
}
}
2005-08-30 16:09:38 +00:00
return newconf ;
2005-08-29 22:01:18 +00:00
}
2005-08-31 02:39:57 +00:00
function upgrade ( subobj , samba3 , message , paths )
2005-08-29 18:52:24 +00:00
{
2005-08-30 12:27:53 +00:00
var ret = 0 ;
2005-08-30 16:09:38 +00:00
var lp = loadparm _init ( ) ;
2005-08-29 18:52:24 +00:00
var samdb = ldb _init ( ) ;
2005-08-31 02:39:57 +00:00
var ok = samdb . connect ( paths . samdb ) ;
2005-08-29 18:52:24 +00:00
assert ( ok ) ;
2005-08-30 16:09:38 +00:00
message ( "Writing configuration\n" ) ;
var newconf = upgrade _smbconf ( samba3 . configuration , true ) ;
2005-08-31 02:39:57 +00:00
newconf . save ( paths . smbconf ) ;
2005-08-30 16:09:38 +00:00
2005-08-29 18:52:24 +00:00
message ( "Importing account policies\n" ) ;
var ldif = upgrade _sam _policy ( samba3 , subobj . BASEDN ) ;
ok = samdb . modify ( ldif ) ;
assert ( ok ) ;
message ( "Importing users\n" ) ;
for ( var i in samba3 . samaccounts ) {
2005-08-31 16:51:09 +00:00
var msg = "... " + samba3 . samaccounts [ i ] . username ;
2005-09-01 00:37:52 +00:00
var ldif = upgrade _sam _account ( samdb , samba3 . samaccounts [ i ] , subobj . BASEDN , subobj . DOMAINSID ) ;
2005-08-29 18:52:24 +00:00
ok = samdb . add ( ldif ) ;
2005-09-01 00:37:52 +00:00
if ( ! ok && samdb . errstring ( ) != "Record exists" ) {
2005-08-31 16:51:09 +00:00
msg = msg + "... error: " + samdb . errstring ( ) ;
2005-08-30 12:27:53 +00:00
ret = ret + 1 ;
}
2005-08-31 16:51:09 +00:00
message ( msg + "\n" ) ;
2005-08-29 18:52:24 +00:00
}
message ( "Importing groups\n" ) ;
for ( var i in samba3 . groupmappings ) {
2005-08-31 16:51:09 +00:00
var msg = "... " + samba3 . groupmappings [ i ] . nt _name ;
2005-08-29 18:52:24 +00:00
var ldif = upgrade _sam _group ( samba3 . groupmappings [ i ] , subobj . BASEDN ) ;
2005-09-01 00:37:52 +00:00
if ( ldif != undefined ) {
ok = samdb . add ( ldif ) ;
if ( ! ok && samdb . errstring ( ) != "Record exists" ) {
msg = msg + "... error: " + samdb . errstring ( ) ;
ret = ret + 1 ;
}
2005-08-30 12:27:53 +00:00
}
2005-08-31 16:51:09 +00:00
message ( msg + "\n" ) ;
2005-08-29 18:52:24 +00:00
}
message ( "Importing registry data\n" ) ;
2005-08-29 20:18:51 +00:00
var hives = new Array ( "hkcr" , "hkcu" , "hklm" , "hkpd" , "hku" , "hkpt" ) ;
2005-08-29 18:52:24 +00:00
for ( var i in hives ) {
2005-08-31 02:39:57 +00:00
var hn = hives [ i ] ;
message ( "... " + hn + "\n" ) ;
2005-08-29 18:52:24 +00:00
var regdb = ldb _init ( ) ;
2005-08-31 02:39:57 +00:00
ok = regdb . connect ( paths [ hn ] ) ;
2005-08-29 18:52:24 +00:00
assert ( ok ) ;
2005-08-31 15:46:41 +00:00
var ldif = upgrade _registry ( samba3 . registry , hn , regdb ) ;
2005-08-30 12:27:53 +00:00
for ( var j in ldif ) {
2005-08-31 16:51:09 +00:00
var msg = "... ... " + j ;
2005-08-30 12:27:53 +00:00
ok = regdb . add ( ldif [ j ] ) ;
2005-09-01 00:37:52 +00:00
if ( ! ok && regdb . errstring ( ) != "Record exists" ) {
2005-08-31 16:51:09 +00:00
msg = msg + "... error: " + regdb . errstring ( ) ;
2005-08-30 12:27:53 +00:00
ret = ret + 1 ;
}
2005-08-31 16:51:09 +00:00
message ( msg + "\n" ) ;
2005-08-30 12:27:53 +00:00
}
2005-08-29 18:52:24 +00:00
}
message ( "Importing WINS data\n" ) ;
var winsdb = ldb _init ( ) ;
2005-08-31 02:39:57 +00:00
ok = winsdb . connect ( paths . winsdb ) ;
2005-08-29 18:52:24 +00:00
assert ( ok ) ;
2005-08-30 12:27:53 +00:00
ldb _erase ( winsdb ) ;
2005-08-29 18:52:24 +00:00
var ldif = upgrade _wins ( samba3 ) ;
ok = winsdb . add ( ldif ) ;
assert ( ok ) ;
2005-08-31 21:04:17 +00:00
// figure out ldapurl, if applicable
var ldapurl = undefined ;
var pdb = samba3 . configuration . get _list ( "passdb backend" ) ;
if ( pdb != undefined ) {
for ( var b in pdb ) {
if ( substr ( pdb [ b ] , 0 , 7 ) == "ldapsam" ) {
ldapurl = substr ( pdb [ b ] , 8 ) ;
}
}
}
// URL was not specified in passdb backend but ldap /is/ used
if ( ldapurl == "" ) {
ldapurl = "ldap://" + samba3 . configuration . get ( "ldap server" ) ;
}
// Enable samba3sam module if original passdb backend was ldap
if ( ldapurl != undefined ) {
message ( "Enabling Samba3 LDAP mappings for SAM database\n" ) ;
2005-09-01 00:37:52 +00:00
ok = samdb . modify ( "
dn : @ MODULES
changetype : modify
2005-08-31 21:04:17 +00:00
replace : @ LIST
2005-09-01 00:37:52 +00:00
@ LIST : samldb , timestamps , objectguid , rdn _name , samba3sam
" ) ;
if ( ! ok ) {
message ( "Error enabling samba3sam module: " + samdb . errstring ( ) + "\n" ) ;
ret = ret + 1 ;
}
2005-09-01 15:33:31 +00:00
ok = samdb . add ( sprintf ( "
dn : @ MAP = samba3sam
@ MAP _URL : % s " , ldapurl ) ) ;
assert ( ok ) ;
2005-08-31 21:04:17 +00:00
}
2005-08-30 12:27:53 +00:00
return ret ;
2005-08-29 18:52:24 +00:00
}
2005-08-31 16:51:09 +00:00
function upgrade _verify ( subobj , samba3 , paths , message )
{
message ( "Verifying account policies\n" ) ;
var samldb = ldb _init ( ) ;
var ne = 0 ;
var ok = samldb . connect ( paths . samdb ) ;
assert ( ok ) ;
2005-09-01 00:37:52 +00:00
for ( var i in samba3 . samaccounts ) {
var msg = samldb . search ( "(&(sAMAccountName=" + samba3 . samaccounts [ i ] . nt _username + ")(objectclass=user))" ) ;
assert ( msg . length >= 1 ) ;
}
2005-08-31 16:51:09 +00:00
// FIXME
}