diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2008-05-23 15:24:40 +0200 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2008-05-23 15:24:40 +0200 |
commit | 7fb26774021986a08d03db968a7826ee64ea7410 (patch) | |
tree | 272d8e4f7671b48c95c817724b41d9c27de1e282 /source4/scripting | |
parent | fd01b27edd5a83306f4ce567e31d43641dd003b8 (diff) | |
parent | 1186579f94d81bc633b8f20e8ad8673313c8c39b (diff) | |
download | samba-7fb26774021986a08d03db968a7826ee64ea7410.tar.gz samba-7fb26774021986a08d03db968a7826ee64ea7410.tar.bz2 samba-7fb26774021986a08d03db968a7826ee64ea7410.zip |
Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into registry
(This used to be commit e8d96b61db1cddc2d8dca45e6e9b53d5c31ee5d4)
Diffstat (limited to 'source4/scripting')
42 files changed, 470 insertions, 1865 deletions
diff --git a/source4/scripting/bin/minschema.py b/source4/scripting/bin/minschema.py index fb9d7b05aa..111557126d 100755 --- a/source4/scripting/bin/minschema.py +++ b/source4/scripting/bin/minschema.py @@ -4,6 +4,12 @@ # import optparse + +import os, sys + +# Find right directory when running from source tree +sys.path.insert(0, "bin/python") + import samba from samba import getopt as options import sys diff --git a/source4/scripting/bin/rpcclient b/source4/scripting/bin/rpcclient index 34efafdf73..aba4f9ddb3 100755 --- a/source4/scripting/bin/rpcclient +++ b/source4/scripting/bin/rpcclient @@ -1,6 +1,10 @@ #!/usr/bin/python import sys, os, string + +# Find right directory when running from source tree +sys.path.insert(0, "bin/python") + from cmd import Cmd from optparse import OptionParser from pprint import pprint diff --git a/source4/scripting/bin/samba3dump b/source4/scripting/bin/samba3dump index 8f56d423d8..d89667233f 100755 --- a/source4/scripting/bin/samba3dump +++ b/source4/scripting/bin/samba3dump @@ -7,7 +7,10 @@ import optparse import os, sys -sys.path.append(os.path.join(os.path.dirname(__file__), "../python")) + +# Find right directory when running from source tree +sys.path.insert(0, "bin/python") + import samba import samba.samba3 diff --git a/source4/scripting/bin/samr.py b/source4/scripting/bin/samr.py new file mode 100755 index 0000000000..e91b5bc312 --- /dev/null +++ b/source4/scripting/bin/samr.py @@ -0,0 +1,114 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Unix SMB/CIFS implementation. +# Copyright © Jelmer Vernooij <jelmer@samba.org> 2008 +# +# Based on samr.js © Andrew Tridgell <tridge@samba.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +import sys + +sys.path.insert(0, "bin/python") + +from samba.dcerpc import samr, security, lsa + +def FillUserInfo(samr, dom_handle, users, level): + """fill a user array with user information from samrQueryUserInfo""" + for i in range(len(users)): + user_handle = samr.OpenUser(handle, security.SEC_FLAG_MAXIMUM_ALLOWED, users[i].idx) + info = samr.QueryUserInfo(user_handle, level) + info.name = users[i].name + info.idx = users[i].idx + users[i] = info + samr.Close(user_handle) + +def toArray((handle, array, num_entries)): + ret = [] + for x in range(num_entries): + ret.append((array.entries[x].idx, array.entries[x].name)) + return ret + + +def test_Connect(samr): + """test the samr_Connect interface""" + print "Testing samr_Connect" + return samr.Connect2(None, security.SEC_FLAG_MAXIMUM_ALLOWED) + +def test_LookupDomain(samr, handle, domain): + """test the samr_LookupDomain interface""" + print "Testing samr_LookupDomain" + return samr.LookupDomain(handle, domain) + +def test_OpenDomain(samr, handle, sid): + """test the samr_OpenDomain interface""" + print "Testing samr_OpenDomain" + return samr.OpenDomain(handle, security.SEC_FLAG_MAXIMUM_ALLOWED, sid) + +def test_EnumDomainUsers(samr, dom_handle): + """test the samr_EnumDomainUsers interface""" + print "Testing samr_EnumDomainUsers" + users = toArray(samr.EnumDomainUsers(dom_handle, 0, 0, -1)) + print "Found %d users" % len(users) + for idx, user in users: + print "\t%s\t(%d)" % (user, idx) + +def test_EnumDomainGroups(samr, dom_handle): + """test the samr_EnumDomainGroups interface""" + print "Testing samr_EnumDomainGroups" + groups = toArray(samr.EnumDomainGroups(dom_handle, 0, 0)) + print "Found %d groups" % len(groups) + for idx, group in groups: + print "\t%s\t(%d)" % (group, idx) + +def test_domain_ops(samr, dom_handle): + """test domain specific ops""" + test_EnumDomainUsers(samr, dom_handle) + test_EnumDomainGroups(samr, dom_handle) + +def test_EnumDomains(samr, handle): + """test the samr_EnumDomains interface""" + print "Testing samr_EnumDomains" + + domains = toArray(samr.EnumDomains(handle, 0, -1)) + print "Found %d domains" % len(domains) + for idx, domain in domains: + print "\t%s (%d)" % (domain, idx) + for idx, domain in domains: + print "Testing domain %s" % domain + sid = samr.LookupDomain(handle, domain) + dom_handle = test_OpenDomain(samr, handle, sid) + test_domain_ops(samr, dom_handle) + samr.Close(dom_handle) + +if len(sys.argv) != 2: + print "Usage: samr.js <BINDING>" + sys.exit(1) + +binding = sys.argv[1] + +print "Connecting to " + binding +try: + samr = samr.samr(binding) +except Exception, e: + print "Failed to connect to %s: %s" % (binding, e.message) + sys.exit(1) + +handle = test_Connect(samr) +test_EnumDomains(samr, handle) +samr.Close(handle) + +print "All OK" diff --git a/source4/scripting/bin/subunitrun b/source4/scripting/bin/subunitrun index fbbffde42c..6f1086ad37 100755 --- a/source4/scripting/bin/subunitrun +++ b/source4/scripting/bin/subunitrun @@ -17,12 +17,16 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -from subunit import SubunitTestRunner import sys + +# Find right directory when running from source tree +sys.path.insert(0, "bin/python") + +from subunit import SubunitTestRunner from unittest import TestProgram import optparse import os -import param +from samba import param import samba.getopt as options import samba.tests diff --git a/source4/scripting/bin/winreg.py b/source4/scripting/bin/winreg.py index 1e39ee8f78..19d39e56ab 100755 --- a/source4/scripting/bin/winreg.py +++ b/source4/scripting/bin/winreg.py @@ -7,6 +7,10 @@ # import sys + +# Find right directory when running from source tree +sys.path.insert(0, "bin/python") + import winreg import optparse import samba.getopt as options diff --git a/source4/scripting/ejs/config.mk b/source4/scripting/ejs/config.mk index cadd71673c..c1a1ca1f0f 100644 --- a/source4/scripting/ejs/config.mk +++ b/source4/scripting/ejs/config.mk @@ -1,13 +1,13 @@ [SUBSYSTEM::EJSRPC] -EJSRPC_OBJ_FILES = scripting/ejs/ejsrpc.o +EJSRPC_OBJ_FILES = $(ejsscriptsrcdir)/ejsrpc.o [MODULE::smbcalls_config] OUTPUT_TYPE = MERGED_OBJ SUBSYSTEM = smbcalls INIT_FUNCTION = smb_setup_ejs_config -smbcalls_config_OBJ_FILES = scripting/ejs/smbcalls_config.o +smbcalls_config_OBJ_FILES = $(ejsscriptsrcdir)/smbcalls_config.o [MODULE::smbcalls_ldb] OUTPUT_TYPE = MERGED_OBJ @@ -15,7 +15,7 @@ SUBSYSTEM = smbcalls INIT_FUNCTION = smb_setup_ejs_ldb PRIVATE_DEPENDENCIES = LIBLDB SAMDB LIBNDR -smbcalls_ldb_OBJ_FILES = scripting/ejs/smbcalls_ldb.o +smbcalls_ldb_OBJ_FILES = $(ejsscriptsrcdir)/smbcalls_ldb.o [MODULE::smbcalls_reg] SUBSYSTEM = smbcalls @@ -23,21 +23,21 @@ OUTPUT_TYPE = MERGED_OBJ INIT_FUNCTION = smb_setup_ejs_reg PRIVATE_DEPENDENCIES = registry SAMDB LIBNDR -smbcalls_reg_OBJ_FILES = scripting/ejs/smbcalls_reg.o +smbcalls_reg_OBJ_FILES = $(ejsscriptsrcdir)/smbcalls_reg.o [MODULE::smbcalls_nbt] SUBSYSTEM = smbcalls OUTPUT_TYPE = MERGED_OBJ INIT_FUNCTION = smb_setup_ejs_nbt -smbcalls_nbt_OBJ_FILES = scripting/ejs/smbcalls_nbt.o +smbcalls_nbt_OBJ_FILES = $(ejsscriptsrcdir)/smbcalls_nbt.o [MODULE::smbcalls_rand] SUBSYSTEM = smbcalls OUTPUT_TYPE = MERGED_OBJ INIT_FUNCTION = smb_setup_ejs_random -smbcalls_rand_OBJ_FILES = scripting/ejs/smbcalls_rand.o +smbcalls_rand_OBJ_FILES = $(ejsscriptsrcdir)/smbcalls_rand.o [MODULE::smbcalls_nss] SUBSYSTEM = smbcalls @@ -45,41 +45,42 @@ OUTPUT_TYPE = MERGED_OBJ INIT_FUNCTION = smb_setup_ejs_nss PRIVATE_DEPENDENCIES = NSS_WRAPPER -smbcalls_nss_OBJ_FILES = scripting/ejs/smbcalls_nss.o +smbcalls_nss_OBJ_FILES = $(ejsscriptsrcdir)/smbcalls_nss.o [MODULE::smbcalls_data] SUBSYSTEM = smbcalls OUTPUT_TYPE = MERGED_OBJ INIT_FUNCTION = smb_setup_ejs_datablob -smbcalls_data_OBJ_FILES = scripting/ejs/smbcalls_data.o +smbcalls_data_OBJ_FILES = $(ejsscriptsrcdir)/smbcalls_data.o [MODULE::smbcalls_auth] OUTPUT_TYPE = MERGED_OBJ SUBSYSTEM = smbcalls INIT_FUNCTION = smb_setup_ejs_auth -PRIVATE_DEPENDENCIES = auth +PRIVATE_DEPENDENCIES = service_auth -smbcalls_auth_OBJ_FILES = scripting/ejs/smbcalls_auth.o +smbcalls_auth_OBJ_FILES = $(ejsscriptsrcdir)/smbcalls_auth.o + +smbcalls_auth_OBJ_FILES = $(ejsscriptsrcdir)/smbcalls_auth.o [MODULE::smbcalls_string] SUBSYSTEM = smbcalls OUTPUT_TYPE = MERGED_OBJ INIT_FUNCTION = smb_setup_ejs_string -smbcalls_string_OBJ_FILES = scripting/ejs/smbcalls_string.o +smbcalls_string_OBJ_FILES = $(ejsscriptsrcdir)/smbcalls_string.o [MODULE::smbcalls_sys] SUBSYSTEM = smbcalls OUTPUT_TYPE = MERGED_OBJ INIT_FUNCTION = smb_setup_ejs_system -smbcalls_sys_OBJ_FILES = scripting/ejs/smbcalls_sys.o +smbcalls_sys_OBJ_FILES = $(ejsscriptsrcdir)/smbcalls_sys.o mkinclude ejsnet/config.mk [SUBSYSTEM::smbcalls] -PRIVATE_PROTO_HEADER = proto.h PRIVATE_DEPENDENCIES = \ EJS LIBSAMBA-UTIL \ EJSRPC MESSAGING \ @@ -88,7 +89,7 @@ PRIVATE_DEPENDENCIES = \ dcerpc \ NDR_TABLE -smbcalls_OBJ_FILES = $(addprefix scripting/ejs/, \ +smbcalls_OBJ_FILES = $(addprefix $(ejsscriptsrcdir)/, \ smbcalls.o \ smbcalls_cli.o \ smbcalls_rpc.o \ @@ -98,6 +99,8 @@ smbcalls_OBJ_FILES = $(addprefix scripting/ejs/, \ mprutil.o \ literal.o) +$(eval $(call proto_header_template,$(ejsscriptsrcdir)/proto.h,$(smbcalls_OBJ_FILES:.o=.c))) + ####################### # Start BINARY SMBSCRIPT [BINARY::smbscript] @@ -105,4 +108,4 @@ PRIVATE_DEPENDENCIES = EJS LIBSAMBA-UTIL smbcalls LIBSAMBA-HOSTCONFIG # End BINARY SMBSCRIPT ####################### -smbscript_OBJ_FILES = scripting/ejs/smbscript.o +smbscript_OBJ_FILES = $(ejsscriptsrcdir)/smbscript.o diff --git a/source4/scripting/ejs/ejsnet/config.mk b/source4/scripting/ejs/ejsnet/config.mk index 85a5b2bf09..710221e37d 100644 --- a/source4/scripting/ejs/ejsnet/config.mk +++ b/source4/scripting/ejs/ejsnet/config.mk @@ -1,13 +1,13 @@ [MODULE::smbcalls_net] SUBSYSTEM = smbcalls INIT_FUNCTION = smb_setup_ejs_net -PRIVATE_PROTO_HEADER = proto.h PRIVATE_DEPENDENCIES = LIBSAMBA-NET LIBCLI_SMB CREDENTIALS -smbcalls_net_OBJ_FILES = $(addprefix scripting/ejs/ejsnet/, \ +smbcalls_net_OBJ_FILES = $(addprefix $(ejsscriptsrcdir)/ejsnet/, \ net_ctx.o \ net_user.o \ mpr_user.o \ net_host.o \ mpr_host.o) +$(eval $(call proto_header_template,$(ejsscriptsrcdir)/ejsnet/proto.h,$(smbcalls_net_OBJ_FILES:.o=.c))) diff --git a/source4/scripting/ejs/ejsnet/net_ctx.c b/source4/scripting/ejs/ejsnet/net_ctx.c index 99be1c4ef8..cbe163552e 100644 --- a/source4/scripting/ejs/ejsnet/net_ctx.c +++ b/source4/scripting/ejs/ejsnet/net_ctx.c @@ -50,7 +50,7 @@ static int ejs_net_context(MprVarHandle eid, int argc, struct MprVar **argv) ejsSetErrorMsg(eid, "talloc_new() failed"); return -1; } - ev = event_context_find(event_mem_ctx); + ev = mprEventCtx(); ctx = libnet_context_init(ev, mprLpCtx()); /* IF we generated a new event context, it will be under here, diff --git a/source4/scripting/ejs/ejsnet/net_user.c b/source4/scripting/ejs/ejsnet/net_user.c index 57e538d3b4..0c32035c6c 100644 --- a/source4/scripting/ejs/ejsnet/net_user.c +++ b/source4/scripting/ejs/ejsnet/net_user.c @@ -268,8 +268,9 @@ static int ejs_net_userinfo(MprVarHandle eid, int argc, char **argv) /* call the libnet function */ req.in.domain_name = userman_domain; - req.in.user_name = username; - + req.in.data.user_name = username; + req.in.level = USER_INFO_BY_NAME; + status = libnet_UserInfo(ctx, mem_ctx, &req); if (!NT_STATUS_IS_OK(status)) { ejsSetErrorMsg(eid, "%s", req.out.error_string); diff --git a/source4/scripting/ejs/smbcalls.c b/source4/scripting/ejs/smbcalls.c index b1a2f6a37b..98d6be07bf 100644 --- a/source4/scripting/ejs/smbcalls.c +++ b/source4/scripting/ejs/smbcalls.c @@ -23,7 +23,6 @@ #include "includes.h" #include "param/param.h" #include "scripting/ejs/smbcalls.h" -#include "build.h" #include "version.h" /* diff --git a/source4/scripting/ejs/smbcalls_auth.c b/source4/scripting/ejs/smbcalls_auth.c index 908a009159..b67bb7ed5b 100644 --- a/source4/scripting/ejs/smbcalls_auth.c +++ b/source4/scripting/ejs/smbcalls_auth.c @@ -55,7 +55,7 @@ static int ejs_doauth(MprVarHandle eid, msg = c->msg_ctx; } else { /* Hope we can find the event context somewhere up there... */ - ev = event_context_find(tmp_ctx); + ev = mprEventCtx(); msg = messaging_client_init(tmp_ctx, lp_messaging_path(tmp_ctx, mprLpCtx()), lp_iconv_convenience(mprLpCtx()), ev); } @@ -109,7 +109,7 @@ static int ejs_doauth(MprVarHandle eid, goto done; } - nt_status = auth_generate_session_info(tmp_ctx, mprLpCtx(), server_info, &session_info); + nt_status = auth_generate_session_info(tmp_ctx, mprEventCtx(), mprLpCtx(), server_info, &session_info); if (!NT_STATUS_IS_OK(nt_status)) { mprSetPropertyValue(auth, "report", mprString("Session Info generation failed")); mprSetPropertyValue(auth, "result", mprCreateBoolVar(false)); diff --git a/source4/scripting/ejs/smbcalls_ldb.c b/source4/scripting/ejs/smbcalls_ldb.c index f47920b9bb..4a157945af 100644 --- a/source4/scripting/ejs/smbcalls_ldb.c +++ b/source4/scripting/ejs/smbcalls_ldb.c @@ -453,7 +453,7 @@ static int ejs_ldbConnect(MprVarHandle eid, int argc, char **argv) dbfile = argv[0]; - ldb = ldb_wrap_connect(mprMemCtx(), mprLpCtx(), dbfile, + ldb = ldb_wrap_connect(mprMemCtx(), mprEventCtx(), mprLpCtx(), dbfile, session_info, creds, 0, (const char **)(argv+1)); if (ldb == NULL) { diff --git a/source4/scripting/ejs/smbcalls_nbt.c b/source4/scripting/ejs/smbcalls_nbt.c index 67a85414ca..8c555bf821 100644 --- a/source4/scripting/ejs/smbcalls_nbt.c +++ b/source4/scripting/ejs/smbcalls_nbt.c @@ -70,7 +70,7 @@ static int ejs_resolve_name(MprVarHandle eid, int argc, struct MprVar **argv) result = 0; - nt_status = resolve_name(lp_resolve_context(mprLpCtx()), &name, tmp_ctx, &reply_addr, event_context_find(tmp_ctx)); + nt_status = resolve_name(lp_resolve_context(mprLpCtx()), &name, tmp_ctx, &reply_addr, mprEventCtx()); if (NT_STATUS_IS_OK(nt_status)) { mprSetPropertyValue(argv[0], "value", mprString(reply_addr)); diff --git a/source4/scripting/ejs/smbcalls_reg.c b/source4/scripting/ejs/smbcalls_reg.c index e20d91ad2e..ed8653d3a7 100644 --- a/source4/scripting/ejs/smbcalls_reg.c +++ b/source4/scripting/ejs/smbcalls_reg.c @@ -70,7 +70,7 @@ static int ejs_reg_open(MprVarHandle eid, int argc, struct MprVar **argv) struct registry_context *rctx; WERROR error; - error = reg_open_samba(mprMemCtx(), &rctx, mprLpCtx(), NULL, NULL); + error = reg_open_samba(mprMemCtx(), &rctx, mprEventCtx(), mprLpCtx(), NULL, NULL); SMB_ASSERT(W_ERROR_IS_OK(error)); mprSetPtrChild(reg, "registry", rctx); diff --git a/source4/scripting/ejs/smbcalls_rpc.c b/source4/scripting/ejs/smbcalls_rpc.c index d1e49b4348..94774d708b 100644 --- a/source4/scripting/ejs/smbcalls_rpc.c +++ b/source4/scripting/ejs/smbcalls_rpc.c @@ -73,7 +73,7 @@ static int ejs_irpc_connect(MprVarHandle eid, int argc, char **argv) p->server_name = argv[0]; - ev = event_context_find(p); + ev = mprEventCtx(); /* create a messaging context, looping as we have no way to allocate temporary server ids automatically */ @@ -158,7 +158,7 @@ static int ejs_rpc_connect(MprVarHandle eid, int argc, char **argv) cli_credentials_set_anonymous(creds); } - ev = event_context_find(mprMemCtx()); + ev = mprEventCtx(); status = dcerpc_pipe_connect(this, &p, binding, iface, creds, ev, mprLpCtx()); diff --git a/source4/scripting/libjs/provision.js b/source4/scripting/libjs/provision.js deleted file mode 100644 index 51e2785762..0000000000 --- a/source4/scripting/libjs/provision.js +++ /dev/null @@ -1,1254 +0,0 @@ -/* - backend code for provisioning a Samba4 server - Copyright Andrew Tridgell 2005 - Released under the GNU GPL version 3 or later -*/ - -sys = sys_init(); - -/* - return true if the current install seems to be OK -*/ -function install_ok(session_info, credentials) -{ - var lp = loadparm_init(); - var ldb = ldb_init(); - ldb.session_info = session_info; - ldb.credentials = credentials; - if (lp.get("realm") == "") { - return false; - } - var ok = ldb.connect(lp.get("sam database")); - if (!ok) { - return false; - } - var res = ldb.search("(cn=Administrator)"); - if (res.error != 0 || res.msgs.length != 1) { - return false; - } - return true; -} - -/* - find a user or group from a list of possibilities -*/ -function findnss() -{ - var i; - assert(arguments.length >= 2); - var nssfn = arguments[0]; - for (i=1;i<arguments.length;i++) { - if (nssfn(arguments[i]) != undefined) { - return arguments[i]; - } - } - printf("Unable to find user/group for %s\n", arguments[1]); - assert(i<arguments.length); -} - -/* - add a foreign security principle - */ -function add_foreign(ldb, subobj, sid, desc) -{ - var add = sprintf(" -dn: CN=%s,CN=ForeignSecurityPrincipals,%s -objectClass: top -objectClass: foreignSecurityPrincipal -description: %s -", - sid, subobj.DOMAINDN, desc); - /* deliberately ignore errors from this, as the records may - already exist */ - ldb.add(add); -} - - -/* - setup a mapping between a sam name and a unix name - */ -function setup_name_mapping(info, ldb, sid, unixname) -{ - var attrs = new Array("dn"); - var res = ldb.search(sprintf("objectSid=%s", sid), - info.subobj.DOMAINDN, ldb.SCOPE_SUBTREE, attrs); - if (res.error != 0 || res.msgs.length != 1) { - info.message("Failed to find record for objectSid %s\n", sid); - return false; - } - var mod = sprintf(" -dn: %s -changetype: modify -replace: unixName -unixName: %s -", - res.msgs[0].dn, unixname); - var ok = ldb.modify(mod); - if (ok.error != 0) { - info.message("name mapping for %s failed - %s\n", - sid, ldb.errstring()); - return false; - } - return true; -} - -/* - return current time as a nt time string -*/ -function nttime() -{ - return "" + sys.nttime(); -} - -/* - return current time as a ldap time string -*/ -function ldaptime() -{ - return sys.ldaptime(sys.nttime()); -} - -/* - return a date string suitable for a dns zone serial number -*/ -function datestring() -{ - var t = sys.ntgmtime(sys.nttime()); - return sprintf("%04u%02u%02u%02u", - t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour); -} - -/* - return first host IP -*/ -function hostip() -{ - var list = sys.interfaces(); - return list[0]; -} - - -/* - return first part of hostname -*/ -function hostname() -{ - var s = split(".", sys.hostname()); - return s[0]; -} - -/* the ldb is in bad shape, possibly due to being built from an - incompatible previous version of the code, so delete it - completely */ -function ldb_delete(info, ldb) -{ - info.message("Deleting " + ldb.filename + "\n"); - var lp = loadparm_init(); - sys.unlink(sprintf("%s/%s", lp.get("private dir"), ldb.filename)); - ldb.transaction_cancel(); - ldb.close(); - var ok = ldb.connect(ldb.filename); - ldb.transaction_start(); - assert(ok); -} - -/* - erase an ldb, removing all records -*/ -function ldb_erase(info, ldb) -{ - var res; - - /* delete the specials */ - ldb.del("@INDEXLIST"); - ldb.del("@ATTRIBUTES"); - ldb.del("@OPTIONS"); - ldb.del("@MODULES"); - ldb.del("@PARTITION"); - ldb.del("@KLUDGEACL"); - - /* and the rest */ - attrs = new Array("dn"); - var basedn = ""; - var res = ldb.search("(&(|(objectclass=*)(distinguishedName=*))(!(distinguishedName=@BASEINFO)))", basedn, ldb.SCOPE_SUBTREE, attrs); - var i; - if (res.error != 0) { - ldb_delete(info, ldb); - return; - } - for (i=0;i<res.msgs.length;i++) { - ldb.del(res.msgs[i].dn); - } - - var res = ldb.search("(&(|(objectclass=*)(distinguishedName=*))(!(distinguishedName=@BASEINFO)))", basedn, ldb.SCOPE_SUBTREE, attrs); - if (res.error != 0 || res.msgs.length != 0) { - ldb_delete(info, ldb); - return; - } - assert(res.msgs.length == 0); -} - -/* - erase an ldb, removing all records -*/ -function ldb_erase_partitions(info, ldb, ldapbackend) -{ - var rootDSE_attrs = new Array("namingContexts"); - var lp = loadparm_init(); - var j; - - var res = ldb.search("(objectClass=*)", "", ldb.SCOPE_BASE, rootDSE_attrs); - if (res.error != 0) { - info.message("rootdse search failed: " + res.errstr + "\n"); - assert(res.error == 0); - } - assert(res.msgs.length == 1); - if (typeof(res.msgs[0].namingContexts) == "undefined") { - return; - } - for (j=0; j<res.msgs[0].namingContexts.length; j++) { - var anything = "(|(objectclass=*)(distinguishedName=*))"; - var attrs = new Array("distinguishedName"); - var basedn = res.msgs[0].namingContexts[j]; - var k; - var previous_remaining = 1; - var current_remaining = 0; - - if (ldapbackend && (basedn == info.subobj.DOMAINDN)) { - /* Only delete objects that were created by provision */ - anything = "(objectcategory=*)"; - } - - for (k=0; k < 10 && (previous_remaining != current_remaining); k++) { - /* and the rest */ - var res2 = ldb.search(anything, basedn, ldb.SCOPE_SUBTREE, attrs); - var i; - if (res2.error != 0) { - if (res2.error == 32) { - break; - } else { - info.message("ldb search(2) failed: " + res2.errstr + "\n"); - continue; - } - } - previous_remaining = current_remaining; - current_remaining = res2.msgs.length; - for (i=0;i<res2.msgs.length;i++) { - ldb.del(res2.msgs[i].dn); - } - - var res3 = ldb.search(anything, basedn, ldb.SCOPE_SUBTREE, attrs); - if (res3.error != 0) { - info.message("ldb search(3) failed: " + res3.errstr + "\n"); - continue; - } - if (res3.msgs.length != 0) { - info.message("Failed to delete all records under " + basedn + ", " + res3.msgs.length + " records remaining\n"); - } - } - } -} - -function open_ldb(info, dbname, erase) -{ - var ldb = ldb_init(); - ldb.session_info = info.session_info; - ldb.credentials = info.credentials; - ldb.filename = dbname; - - var connect_ok = ldb.connect(dbname); - if (!connect_ok) { - var lp = loadparm_init(); - sys.unlink(sprintf("%s/%s", lp.get("private dir"), dbname)); - connect_ok = ldb.connect(dbname); - assert(connect_ok); - } - - ldb.transaction_start(); - - if (erase) { - ldb_erase(info, ldb); - } - return ldb; -} - - -/* - setup a ldb in the private dir - */ -function setup_add_ldif(ldif, info, ldb, failok) -{ - var lp = loadparm_init(); - var src = lp.get("setup directory") + "/" + ldif; - - var data = sys.file_load(src); - data = substitute_var(data, info.subobj); - - var add_res = ldb.add(data); - if (add_res.error != 0) { - info.message("ldb load failed: " + add_res.errstr + "\n"); - if (!failok) { - assert(add_res.error == 0); - } - } - return (add_res.error == 0); -} - -function setup_modify_ldif(ldif, info, ldb, failok) -{ - var lp = loadparm_init(); - var src = lp.get("setup directory") + "/" + ldif; - - var data = sys.file_load(src); - data = substitute_var(data, info.subobj); - - var mod_res = ldb.modify(data); - if (mod_res.error != 0) { - info.message("ldb load failed: " + mod_res.errstr + "\n"); - if (!failok) { - assert(mod_res.error == 0); - } - } - return (mod_res.error == 0); -} - - -function setup_ldb(ldif, info, dbname) -{ - var erase = true; - var failok = false; - - if (arguments.length >= 4) { - erase = arguments[3]; - } - if (arguments.length == 5) { - failok = arguments[4]; - } - var ldb = open_ldb(info, dbname, erase); - if (setup_add_ldif(ldif, info, ldb, failok)) { - var commit_ok = ldb.transaction_commit(); - if (!commit_ok) { - info.message("ldb commit failed: " + ldb.errstring() + "\n"); - assert(commit_ok); - } - } -} - -/* - setup a ldb in the private dir - */ -function setup_ldb_modify(ldif, info, ldb) -{ - var lp = loadparm_init(); - - var src = lp.get("setup directory") + "/" + ldif; - - var data = sys.file_load(src); - data = substitute_var(data, info.subobj); - - var mod_res = ldb.modify(data); - if (mod_res.error != 0) { - info.message("ldb load failed: " + mod_res.errstr + "\n"); - return (mod_res.error == 0); - } - return (mod_res.error == 0); -} - -/* - setup a file in the private dir - */ -function setup_file(template, message, fname, subobj) -{ - var lp = loadparm_init(); - var f = fname; - var src = lp.get("setup directory") + "/" + template; - - if (! sys.stat(src)) { - message("Template file not found: %s\n",src); - assert(0); - } - - sys.unlink(f); - - var data = sys.file_load(src); - data = substitute_var(data, subobj); - - ok = sys.file_save(f, data); - if (!ok) { - message("failed to create file: " + f + "\n"); - assert(ok); - } -} - -function provision_default_paths(subobj) -{ - /* subobj.DNSDOMAIN isn't available at this point */ - var dnsdomain = strlower(subobj.REALM); - var lp = loadparm_init(); - var paths = new Object(); - paths.smbconf = lp.filename() - paths.shareconf = lp.get("private dir") + "/" + "share.ldb"; - paths.samdb = lp.get("sam database"); - paths.idmapdb = lp.get("idmap database"); - paths.secrets = lp.get("secrets database"); - paths.templates = lp.get("private dir") + "/" + "templates.ldb"; - paths.keytab = "secrets.keytab"; - paths.dns_keytab = "dns.keytab"; - paths.dns_keytab_abs = lp.get("private dir") + "/" + paths.dns_keytab; - paths.dns = lp.get("private dir") + "/" + dnsdomain + ".zone"; - paths.named_conf = lp.get("private dir") + "/named.conf"; - paths.winsdb = "wins.ldb"; - paths.ldapdir = lp.get("private dir") + "/ldap"; - - paths.s4_ldapi_socket = lp.get("private dir") + "/ldapi"; - paths.phpldapadminconfig = lp.get("private dir") + "/phpldapadmin-config.php"; - - paths.sysvol = lp.get("sysvol", "path"); - - if (paths.sysvol == undefined) { - paths.sysvol = lp.get("lock dir") + "/sysvol"; - } - - paths.netlogon = lp.get("netlogon", "path"); - - if (paths.netlogon == undefined) { - paths.netlogon = paths.sysvol + "/" + dnsdomain + "/scripts"; - } - - return paths; -} - - -/* - setup reasonable name mappings for sam names to unix names -*/ -function setup_name_mappings(info, ldb) -{ - var lp = loadparm_init(); - var attrs = new Array("objectSid"); - var subobj = info.subobj; - - res = ldb.search("objectSid=*", subobj.DOMAINDN, ldb.SCOPE_BASE, attrs); - assert(res.error == 0); - assert(res.msgs.length == 1 && res.msgs[0].objectSid != undefined); - var sid = res.msgs[0].objectSid; - - /* add some foreign sids if they are not present already */ - add_foreign(ldb, subobj, "S-1-5-7", "Anonymous"); - add_foreign(ldb, subobj, "S-1-1-0", "World"); - add_foreign(ldb, subobj, "S-1-5-2", "Network"); - add_foreign(ldb, subobj, "S-1-5-18", "System"); - add_foreign(ldb, subobj, "S-1-5-11", "Authenticated Users"); - - /* some well known sids */ - setup_name_mapping(info, ldb, "S-1-5-7", subobj.NOBODY); - setup_name_mapping(info, ldb, "S-1-1-0", subobj.NOGROUP); - setup_name_mapping(info, ldb, "S-1-5-2", subobj.NOGROUP); - setup_name_mapping(info, ldb, "S-1-5-18", subobj.ROOT); - setup_name_mapping(info, ldb, "S-1-5-11", subobj.USERS); - setup_name_mapping(info, ldb, "S-1-5-32-544", subobj.WHEEL); - setup_name_mapping(info, ldb, "S-1-5-32-545", subobj.USERS); - setup_name_mapping(info, ldb, "S-1-5-32-546", subobj.NOGROUP); - setup_name_mapping(info, ldb, "S-1-5-32-551", subobj.BACKUP); - - /* and some well known domain rids */ - setup_name_mapping(info, ldb, sid + "-500", subobj.ROOT); - setup_name_mapping(info, ldb, sid + "-518", subobj.WHEEL); - setup_name_mapping(info, ldb, sid + "-519", subobj.WHEEL); - setup_name_mapping(info, ldb, sid + "-512", subobj.WHEEL); - setup_name_mapping(info, ldb, sid + "-513", subobj.USERS); - setup_name_mapping(info, ldb, sid + "-520", subobj.WHEEL); - - return true; -} - -function provision_fix_subobj(subobj, paths) -{ - var ldb = ldb_init(); - - subobj.REALM = strupper(subobj.REALM); - subobj.HOSTNAME = strlower(subobj.HOSTNAME); - subobj.DOMAIN = strupper(subobj.DOMAIN); - subobj.NETBIOSNAME = strupper(subobj.HOSTNAME); - subobj.DNSDOMAIN = strlower(subobj.REALM); - subobj.DNSNAME = sprintf("%s.%s", - strlower(subobj.HOSTNAME), - subobj.DNSDOMAIN); - var rdn_list = split(".", subobj.DNSDOMAIN); - subobj.DOMAINDN = "DC=" + join(",DC=", rdn_list); - subobj.ROOTDN = subobj.DOMAINDN; - subobj.CONFIGDN = "CN=Configuration," + subobj.ROOTDN; - subobj.SCHEMADN = "CN=Schema," + subobj.CONFIGDN; - - subobj.MACHINEPASS_B64 = ldb.encode(subobj.MACHINEPASS); - subobj.KRBTGTPASS_B64 = ldb.encode(subobj.KRBTGTPASS); - subobj.ADMINPASS_B64 = ldb.encode(subobj.ADMINPASS); - subobj.DNSPASS_B64 = ldb.encode(subobj.DNSPASS); - - subobj.SAM_LDB = "tdb://" + paths.samdb; - subobj.SECRETS_KEYTAB = paths.keytab; - subobj.DNS_KEYTAB = paths.dns_keytab; - subobj.DNS_KEYTAB_ABS = paths.dns_keytab_abs; - - subobj.LDAPDIR = paths.ldapdir; - var ldap_path_list = split("/", paths.ldapdir); - subobj.LDAPI_URI = "ldapi://" + join("%2F", ldap_path_list) + "%2Fldapi"; - - var s4ldap_path_list = split("/", paths.s4_ldapi_socket); - subobj.S4_LDAPI_URI = "ldapi://" + join("%2F", s4ldap_path_list); - - subobj.LDAPMANAGERDN = "cn=Manager," + subobj.DOMAINDN; - - subobj.NETLOGONPATH = paths.netlogon; - subobj.SYSVOLPATH = paths.sysvol; - - if (subobj.DOMAIN_CONF == undefined) { - subobj.DOMAIN_CONF = subobj.DOMAIN; - } - if (subobj.REALM_CONF == undefined) { - subobj.REALM_CONF = subobj.REALM; - } - if (strlower(subobj.SERVERROLE) != strlower("domain controller")) { - subobj.REALM = subobj.HOSTNAME; - subobj.DOMAIN = subobj.HOSTNAME; - } - - return true; -} - -function provision_become_dc(subobj, message, erase, paths, session_info) -{ - var lp = loadparm_init(); - var sys = sys_init(); - var info = new Object(); - - var ok = provision_fix_subobj(subobj, paths); - assert(ok); - - if (subobj.BACKEND_MOD == undefined) { - subobj.BACKEND_MOD = "repl_meta_data"; - } - - info.subobj = subobj; - info.message = message; - info.session_info = session_info; - - message("Setting up templates into " + paths.templates + "\n"); - setup_ldb("provision_templates.ldif", info, paths.templates); - - /* Also wipes the database */ - message("Setting up " + paths.samdb + " partitions\n"); - setup_ldb("provision_partitions.ldif", info, paths.samdb); - - var samdb = open_ldb(info, paths.samdb, false); - - message("Setting up " + paths.samdb + " attributes\n"); - setup_add_ldif("provision_init.ldif", info, samdb, false); - - message("Setting up " + paths.samdb + " rootDSE\n"); - setup_add_ldif("provision_rootdse_add.ldif", info, samdb, false); - - if (erase) { - message("Erasing data from partitions\n"); - ldb_erase_partitions(info, samdb, undefined); - } - - message("Setting up " + paths.samdb + " indexes\n"); - setup_add_ldif("provision_index.ldif", info, samdb, false); - - ok = samdb.transaction_commit(); - assert(ok); - - message("Setting up " + paths.secrets + "\n"); - setup_ldb("secrets_init.ldif", info, paths.secrets); - - setup_ldb("secrets.ldif", info, paths.secrets, false); - - setup_ldb("secrets_dc.ldif", info, paths.secrets, false); - - return true; -} - -function load_schema(subobj, message, samdb) -{ - var lp = loadparm_init(); - var src = lp.get("setup directory") + "/" + "schema.ldif"; - - if (! sys.stat(src)) { - message("Template file not found: %s\n",src); - assert(0); - } - - var schema_data = sys.file_load(src); - - src = lp.get("setup directory") + "/" + "schema_samba4.ldif"; - - if (! sys.stat(src)) { - message("Template file not found: %s\n",src); - assert(0); - } - - schema_data = schema_data + sys.file_load(src); - - schema_data = substitute_var(schema_data, subobj); - - src = lp.get("setup directory") + "/" + "provision_schema_basedn_modify.ldif"; - - if (! sys.stat(src)) { - message("Template file not found: %s\n",src); - assert(0); - } - - var head_data = sys.file_load(src); - head_data = substitute_var(head_data, subobj); - - var ok = samdb.attach_dsdb_schema_from_ldif(head_data, schema_data); - return ok; -} - - -/* - provision samba4 - caution, this wipes all existing data! -*/ -function provision(subobj, message, blank, paths, session_info, credentials, ldapbackend) -{ - var lp = loadparm_init(); - var sys = sys_init(); - var info = new Object(); - random_init(local); - - var ok = provision_fix_subobj(subobj, paths); - assert(ok); - - if (strlower(subobj.SERVERROLE) == strlower("domain controller")) { - if (subobj.BACKEND_MOD == undefined) { - subobj.BACKEND_MOD = "repl_meta_data"; - } - } else { - if (subobj.BACKEND_MOD == undefined) { - subobj.BACKEND_MOD = "objectguid"; - } - } - - if (subobj.DOMAINGUID != undefined) { - subobj.DOMAINGUID_MOD = sprintf("replace: objectGUID\nobjectGUID: %s\n-", subobj.DOMAINGUID); - } else { - subobj.DOMAINGUID_MOD = ""; - } - - if (subobj.HOSTGUID != undefined) { - subobj.HOSTGUID_ADD = sprintf("objectGUID: %s", subobj.HOSTGUID); - } else { - subobj.HOSTGUID_ADD = ""; - } - - info.subobj = subobj; - info.message = message; - info.credentials = credentials; - info.session_info = session_info; - - /* only install a new smb.conf if there isn't one there already */ - var st = sys.stat(paths.smbconf); - if (st == undefined) { - var smbconfsuffix; - if (strlower(subobj.SERVERROLE) == strlower("domain controller")) { - smbconfsuffix = "dc"; - } else if (strlower(subobj.SERVERROLE) == strlower("member server")) { - smbconfsuffix = "member"; - } else { - smbconfsuffix = subobj.SERVERROLE; - } - message("Setting up " + paths.smbconf +"\n"); - setup_file("provision.smb.conf." + smbconfsuffix, info.message, paths.smbconf, subobj); - lp.reload(); - } - /* only install a new shares config db if there is none */ - st = sys.stat(paths.shareconf); - if (st == undefined) { - message("Setting up share.ldb\n"); - setup_ldb("share.ldif", info, paths.shareconf); - } - - message("Setting up " + paths.secrets + "\n"); - setup_ldb("secrets_init.ldif", info, paths.secrets); - setup_ldb("secrets.ldif", info, paths.secrets, false); - - message("Setting up the registry\n"); - var reg = reg_open(); - reg.apply_patchfile(lp.get("setup directory") + "/provision.reg") - - message("Setting up templates into " + paths.templates + "\n"); - setup_ldb("provision_templates.ldif", info, paths.templates); - - message("Setting up " + paths.idmapdb +"\n"); - setup_ldb("idmap_init.ldif", info, paths.idmapdb); - - message("Setting up sam.ldb partitions\n"); - /* Also wipes the database */ - setup_ldb("provision_partitions.ldif", info, paths.samdb); - - var samdb = open_ldb(info, paths.samdb, false); - - message("Setting up sam.ldb attributes\n"); - setup_add_ldif("provision_init.ldif", info, samdb, false); - - message("Setting up sam.ldb rootDSE\n"); - setup_add_ldif("provision_rootdse_add.ldif", info, samdb, false); - - message("Erasing data from partitions\n"); - ldb_erase_partitions(info, samdb, ldapbackend); - - // (hack) Reload, now we have the partitions and rootdse loaded. - var commit_ok = samdb.transaction_commit(); - if (!commit_ok) { - info.message("samdb commit failed: " + samdb.errstring() + "\n"); - assert(commit_ok); - } - samdb.close(); - - message("Pre-loading the Samba4 and AD schema\n"); - - samdb = open_ldb(info, paths.samdb, false); - - samdb.set_domain_sid(subobj.DOMAINSID); - - if (strlower(subobj.SERVERROLE) == strlower("domain controller")) { - if (subobj.INVOCATIONID == undefined) { - subobj.INVOCATIONID = randguid(); - } - samdb.set_ntds_invocationId(subobj.INVOCATIONID); - if (subobj.BACKEND_MOD == undefined) { - subobj.BACKEND_MOD = "repl_meta_data"; - } - } else { - if (subobj.BACKEND_MOD == undefined) { - subobj.BACKEND_MOD = "objectguid"; - } - } - - var load_schema_ok = load_schema(subobj, message, samdb); - assert(load_schema_ok.is_ok); - - message("Adding DomainDN: " + subobj.DOMAINDN + " (permitted to fail)\n"); - var add_ok = setup_add_ldif("provision_basedn.ldif", info, samdb, true); - message("Modifying DomainDN: " + subobj.DOMAINDN + "\n"); - var modify_basedn_ok = setup_ldb_modify("provision_basedn_modify.ldif", info, samdb); - if (!modify_basedn_ok) { - if (!add_ok) { - message("%s", "Failed to both add and modify " + subobj.DOMAINDN + " in target " + subobj.DOMAINDN_LDB + ": " + samdb.errstring() + "\n"); - message("Perhaps you need to run the provision script with the --ldap-base-dn option, and add this record to the backend manually\n"); - }; - assert(modify_basedn_ok); - }; - - message("Adding configuration container (permitted to fail)\n"); - var add_config_ok = setup_add_ldif("provision_configuration_basedn.ldif", info, samdb, true); - message("Modifying configuration container\n"); - var modify_config_ok = setup_ldb_modify("provision_configuration_basedn_modify.ldif", info, samdb); - if (!modify_config_ok) { - if (!add_config_ok) { - message("%s", "Failed to both add and modify " + subobj.CONFIGDN + " in target " + subobj.CONFIGDN_LDB + ": " + samdb.errstring() + "\n"); - message("Perhaps you need to run the provision script with the --ldap-base-dn option, and add this record to the backend manually\n"); - } - assert(modify_config_ok); - } - - message("Adding schema container (permitted to fail)\n"); - var add_schema_ok = setup_add_ldif("provision_schema_basedn.ldif", info, samdb, true); - message("Modifying schema container\n"); - var modify_schema_ok = setup_ldb_modify("provision_schema_basedn_modify.ldif", info, samdb); - if (!modify_schema_ok) { - if (!add_schema_ok) { - message("%s", "Failed to both add and modify " + subobj.SCHEMADN + " in target " + subobj.SCHEMADN_LDB + ": " + samdb.errstring() + "\n"); - message("Perhaps you need to run the provision script with the --ldap-base-dn option, and add this record to the backend manually\n"); - } - message("Failed to modify the schema container: " + samdb.errstring() + "\n"); - assert(modify_schema_ok); - } - - message("Setting up sam.ldb Samba4 schema\n"); - setup_add_ldif("schema_samba4.ldif", info, samdb, false); - message("Setting up sam.ldb AD schema\n"); - setup_add_ldif("schema.ldif", info, samdb, false); - - message("Setting up sam.ldb configuration data\n"); - setup_add_ldif("provision_configuration.ldif", info, samdb, false); - - message("Setting up display specifiers\n"); - setup_add_ldif("display_specifiers.ldif", info, samdb, false); - - message("Adding users container (permitted to fail)\n"); - var add_users_ok = setup_add_ldif("provision_users_add.ldif", info, samdb, true); - message("Modifying users container\n"); - var modify_users_ok = setup_ldb_modify("provision_users_modify.ldif", info, samdb); - if (!modify_users_ok) { - if (!add_users_ok) { - message("Failed to both add and modify the users container\n"); - } - assert(modify_users_ok); - } - message("Adding computers container (permitted to fail)\n"); - var add_computers_ok = setup_add_ldif("provision_computers_add.ldif", info, samdb, true); - message("Modifying computers container\n"); - var modify_computers_ok = setup_ldb_modify("provision_computers_modify.ldif", info, samdb); - if (!modify_computers_ok) { - if (!add_computers_ok) { - message("Failed to both add and modify the computers container\n"); - } - assert(modify_computers_ok); - } - - message("Setting up sam.ldb data\n"); - setup_add_ldif("provision.ldif", info, samdb, false); - - if (blank != false) { - message("Setting up sam.ldb index\n"); - setup_add_ldif("provision_index.ldif", info, samdb, false); - - message("Setting up sam.ldb rootDSE marking as syncronized\n"); - setup_modify_ldif("provision_rootdse_modify.ldif", info, samdb, false); - - var commit_ok = samdb.transaction_commit(); - if (!commit_ok) { - info.message("ldb commit failed: " + samdb.errstring() + "\n"); - assert(commit_ok); - } - return true; - } - -// message("Activate schema module"); -// setup_modify_ldif("schema_activation.ldif", info, samdb, false); -// -// // (hack) Reload, now we have the schema loaded. -// var commit_ok = samdb.transaction_commit(); -// if (!commit_ok) { -// info.message("samdb commit failed: " + samdb.errstring() + "\n"); -// assert(commit_ok); -// } -// samdb.close(); -// -// samdb = open_ldb(info, paths.samdb, false); -// - message("Setting up sam.ldb users and groups\n"); - setup_add_ldif("provision_users.ldif", info, samdb, false); - - if (strlower(subobj.SERVERROLE) == strlower("domain controller")) { - message("Setting up self join\n"); - setup_add_ldif("provision_self_join.ldif", info, samdb, false); - setup_add_ldif("provision_group_policy.ldif", info, samdb, false); - - sys.mkdir(paths.sysvol, 0755); - sys.mkdir(paths.sysvol + "/"+ subobj.DNSDOMAIN, 0755); - sys.mkdir(paths.sysvol + "/"+ subobj.DNSDOMAIN + "/Policies", 0755); - sys.mkdir(paths.sysvol + "/"+ subobj.DNSDOMAIN + "/Policies/{" + subobj.POLICYGUID + "}", 0755); - sys.mkdir(paths.sysvol + "/"+ subobj.DNSDOMAIN + "/Policies/{" + subobj.POLICYGUID + "}/Machine", 0755); - sys.mkdir(paths.sysvol + "/"+ subobj.DNSDOMAIN + "/Policies/{" + subobj.POLICYGUID + "}/User", 0755); - - sys.mkdir(paths.netlogon, 0755); - - setup_ldb("secrets_dc.ldif", info, paths.secrets, false); - - } - - if (setup_name_mappings(info, samdb) == false) { - return false; - } - - message("Setting up sam.ldb index\n"); - setup_add_ldif("provision_index.ldif", info, samdb, false); - - message("Setting up sam.ldb rootDSE marking as syncronized\n"); - setup_modify_ldif("provision_rootdse_modify.ldif", info, samdb, false); - - var commit_ok = samdb.transaction_commit(); - if (!commit_ok) { - info.message("samdb commit failed: " + samdb.errstring() + "\n"); - assert(commit_ok); - } - - message("Setting up phpLDAPadmin configuration\n"); - setup_file("phpldapadmin-config.php", info.message, paths.phpldapadminconfig, subobj); - message("Please install the phpLDAPadmin configuration located at " + paths.phpldapadminconfig + " into /etc/phpldapadmin/config.php\n"); - - return true; -} - -/* - provision just the schema into a temporary ldb, so we can run ad2oLschema on it -*/ -function provision_schema(subobj, message, tmp_schema_path, paths) -{ - var lp = loadparm_init(); - var sys = sys_init(); - var info = new Object(); - - var ok = provision_fix_subobj(subobj, paths); - assert(ok); - - info.subobj = subobj; - info.message = message; - - message("Setting up sam.ldb partitions\n"); - - /* This will erase anything in the tmp db */ - var samdb = open_ldb(info, tmp_schema_path, true); - - message("Setting up sam.ldb attributes\n"); - setup_add_ldif("provision_init.ldif", info, samdb, false); - - message("Setting up sam.ldb rootDSE\n"); - setup_add_ldif("provision_rootdse_add.ldif", info, samdb, false); - - message("Adding schema container (permitted to fail)\n"); - var add_ok = setup_add_ldif("provision_schema_basedn.ldif", info, samdb, true); - message("Modifying schema container\n"); - var modify_ok = setup_ldb_modify("provision_schema_basedn_modify.ldif", info, samdb); - if (!modify_ok) { - if (!add_ok) { - message("Failed to both add and modify schema dn: " + samdb.errstring() + "\n"); - message("Perhaps you need to run the provision script with the --ldap-base-dn option, and add this record to the backend manually\n"); - assert(modify_ok); - } - message("Failed to modify the schema container: " + samdb.errstring() + "\n"); - assert(modify_ok); - } - - message("Setting up sam.ldb Samba4 schema\n"); - setup_add_ldif("schema_samba4.ldif", info, samdb, false); - message("Setting up sam.ldb AD schema\n"); - setup_add_ldif("schema.ldif", info, samdb, false); - - var commit_ok = samdb.transaction_commit(); - if (!commit_ok) { - info.message("samdb commit failed: " + samdb.errstring() + "\n"); - assert(commit_ok); - } - samdb.close(); -} - -/* Write out a DNS zone file, from the info in the current database */ -function provision_dns(subobj, message, paths, session_info, credentials) -{ - var lp = loadparm_init(); - if (strlower(subobj.SERVERROLE) != strlower("domain controller")) { - message("No DNS zone required for role %s\n", subobj.SERVERROLE); - return; - } - message("Setting up DNS zone: " + subobj.DNSDOMAIN + " \n"); - var ldb = ldb_init(); - ldb.session_info = session_info; - ldb.credentials = credentials; - - /* connect to the sam */ - var ok = ldb.connect(paths.samdb); - assert(ok); - - /* These values may have changed, due to an incoming SamSync, - or may not have been specified, so fetch them from the database */ - - var attrs = new Array("objectGUID"); - res = ldb.search("objectGUID=*", subobj.DOMAINDN, ldb.SCOPE_BASE, attrs); - assert(res.error == 0); - assert(res.msgs.length == 1); - assert(res.msgs[0].objectGUID != undefined); - subobj.DOMAINGUID = res.msgs[0].objectGUID; - - subobj.HOSTGUID = searchone(ldb, subobj.DOMAINDN, "(&(objectClass=computer)(cn=" + subobj.NETBIOSNAME + "))", "objectGUID"); - assert(subobj.HOSTGUID != undefined); - - setup_file("provision.zone", - message, paths.dns, - subobj); - - setup_file("named.conf", - message, paths.named_conf, - subobj); - - message("Please install the zone located in " + paths.dns + " into your DNS server. A sample BIND configuration snippit is at " + paths.named_conf + "\n"); -} - - -/* - guess reasonably default options for provisioning -*/ -function provision_guess() -{ - var subobj = new Object(); - var nss = nss_init(); - var lp = loadparm_init(); - var rdn_list; - random_init(local); - - subobj.SERVERROLE = strlower(lp.get("server role")); - subobj.REALM = strupper(lp.get("realm")); - subobj.DOMAIN = lp.get("workgroup"); - subobj.HOSTNAME = hostname(); - - assert(subobj.REALM); - assert(subobj.DOMAIN); - assert(subobj.HOSTNAME); - - subobj.VERSION = version(); - subobj.HOSTIP = hostip(); - subobj.DOMAINSID = randsid(); - subobj.POLICYGUID = randguid(); - subobj.KRBTGTPASS = randpass(12); - subobj.MACHINEPASS = randpass(12); - subobj.DNSPASS = randpass(12); - subobj.ADMINPASS = randpass(12); - subobj.LDAPMANAGERPASS = randpass(12); - subobj.DEFAULTSITE = "Default-First-Site-Name"; - subobj.DATESTRING = datestring; - subobj.ROOT = findnss(nss.getpwnam, "root"); - subobj.NOBODY = findnss(nss.getpwnam, "nobody"); - subobj.NOGROUP = findnss(nss.getgrnam, "nogroup", "nobody"); - subobj.WHEEL = findnss(nss.getgrnam, "wheel", "root", "staff", "adm"); - subobj.BACKUP = findnss(nss.getgrnam, "backup", "wheel", "root", "staff"); - subobj.USERS = findnss(nss.getgrnam, "users", "guest", "other", "unknown", "usr"); - - //Add modules to the list to activate them by default - //beware often order is important - // - // Some Known ordering constraints: - // - rootdse must be first, as it makes redirects from "" -> cn=rootdse - // - objectclass must be before password_hash, because password_hash checks - // that the objectclass is of type person (filled in by the objectclass - // module when expanding the objectclass list) - // - partition must be last - // - each partition has its own module list then - var modules_list = new Array("rootdse", - "paged_results", - "ranged_results", - "anr", - "server_sort", - "extended_dn", - "asq", - "samldb", - "rdn_name", - "objectclass", - "kludge_acl", - "operational"); - var tdb_modules_list = new Array("subtree_rename", - "subtree_delete", - "linked_attributes"); - var modules_list2 = new Array("show_deleted", - "partition"); - subobj.MODULES_LIST = join(",", modules_list); - subobj.TDB_MODULES_LIST = "," + join(",", tdb_modules_list); - subobj.MODULES_LIST2 = join(",", modules_list2); - subobj.DOMAINDN_LDB = "users.ldb"; - subobj.CONFIGDN_LDB = "configuration.ldb"; - subobj.SCHEMADN_LDB = "schema.ldb"; - subobj.DOMAINDN_MOD = "pdc_fsmo,password_hash,instancetype"; - subobj.CONFIGDN_MOD = "naming_fsmo,instancetype"; - subobj.SCHEMADN_MOD = "schema_fsmo,instancetype"; - - subobj.ACI = "# no aci for local ldb"; - - return subobj; -} - -/* - search for one attribute as a string - */ -function searchone(ldb, basedn, expression, attribute) -{ - var attrs = new Array(attribute); - res = ldb.search(expression, basedn, ldb.SCOPE_SUBTREE, attrs); - if (res.error != 0 || - res.msgs.length != 1 || - res.msgs[0][attribute] == undefined) { - return undefined; - } - return res.msgs[0][attribute]; -} - -/* - modify an account to remove the -*/ -function enable_account(ldb, user_dn) -{ - var attrs = new Array("userAccountControl"); - var res = ldb.search(NULL, user_dn, ldb.SCOPE_ONELEVEL, attrs); - assert(res.error == 0); - assert(res.msgs.length == 1); - var userAccountControl = res.msgs[0].userAccountControl; - userAccountControl = userAccountControl - 2; /* remove disabled bit */ - var mod = sprintf(" -dn: %s -changetype: modify -replace: userAccountControl -userAccountControl: %u -", - user_dn, userAccountControl); - var ok = ldb.modify(mod); - return (ok.error == 0); -} - - -/* - add a new user record -*/ -function newuser(username, unixname, password, message, session_info, credentials) -{ - var lp = loadparm_init(); - var samdb = lp.get("sam database"); - var ldb = ldb_init(); - random_init(local); - ldb.session_info = session_info; - ldb.credentials = credentials; - - /* connect to the sam */ - var ok = ldb.connect(samdb); - assert(ok); - - ldb.transaction_start(); - - /* find the DNs for the domain and the domain users group */ - var attrs = new Array("defaultNamingContext"); - res = ldb.search("defaultNamingContext=*", "", ldb.SCOPE_BASE, attrs); - assert(res.error == 0); - assert(res.msgs.length == 1 && res.msgs[0].defaultNamingContext != undefined); - var domain_dn = res.msgs[0].defaultNamingContext; - assert(domain_dn != undefined); - var dom_users = searchone(ldb, domain_dn, "name=Domain Users", "dn"); - assert(dom_users != undefined); - - var user_dn = sprintf("CN=%s,CN=Users,%s", username, domain_dn); - - - /* - the new user record. note the reliance on the samdb module to fill - in a sid, guid etc - */ - var ldif = sprintf(" -dn: %s -sAMAccountName: %s -unixName: %s -sambaPassword: %s -objectClass: user -", - user_dn, username, - unixname, password); - /* - add the user to the users group as well - */ - var modgroup = sprintf(" -dn: %s -changetype: modify -add: member -member: %s -", - dom_users, user_dn); - - - /* - now the real work - */ - message("Adding user %s\n", user_dn); - ok = ldb.add(ldif); - if (ok.error != 0) { - message("Failed to add %s - %s\n", user_dn, ok.errstr); - return false; - } - - message("Modifying group %s\n", dom_users); - ok = ldb.modify(modgroup); - if (ok.error != 0) { - message("Failed to modify %s - %s\n", dom_users, ok.errstr); - return false; - } - - /* - modify the userAccountControl to remove the disabled bit - */ - ok = enable_account(ldb, user_dn); - if (ok) { - ldb.transaction_commit(); - } - return ok; -} - -// Check whether a name is valid as a NetBIOS name. -// FIXME: There are probably more constraints here. -// crh has a paragraph on this in his book (1.4.1.1) -function valid_netbios_name(name) -{ - if (strlen(name) > 15) return false; - return true; -} - -function provision_validate(subobj, message) -{ - var lp = loadparm_init(); - - if (!valid_netbios_name(subobj.DOMAIN)) { - message("Invalid NetBIOS name for domain\n"); - return false; - } - - if (!valid_netbios_name(subobj.NETBIOSNAME)) { - message("Invalid NetBIOS name for host\n"); - return false; - } - - - if (strupper(lp.get("workgroup")) != strupper(subobj.DOMAIN_CONF)) { - message("workgroup '%s' in smb.conf must match chosen domain '%s'\n", - lp.get("workgroup"), subobj.DOMAIN_CONF); - return false; - } - - if (strupper(lp.get("realm")) != strupper(subobj.REALM_CONF)) { - message("realm '%s' in smb.conf must match chosen realm '%s'\n", - lp.get("realm"), subobj.REALM_CONF); - return false; - } - - if (strlower(lp.get("server role")) != strlower(subobj.SERVERROLE)) { - message("server role '%s' in smb.conf must match chosen role '%s'\n", - lp.get("server role"), subobj.SERVERROLE); - return false; - } - - return true; -} - -function join_domain(domain, netbios_name, join_type, creds, message) -{ - var ctx = NetContext(creds); - var joindom = new Object(); - joindom.domain = domain; - joindom.join_type = join_type; - joindom.netbios_name = netbios_name; - if (!ctx.JoinDomain(joindom)) { - message("Domain Join failed: " + joindom.error_string); - return false; - } - return true; -} - -/* Vampire a remote domain. Session info and credentials are required for for - * access to our local database (might be remote ldap) - */ - -function vampire(domain, session_info, credentials, message) { - var ctx = NetContext(credentials); - var vampire_ctx = new Object(); - var machine_creds = credentials_init(); - machine_creds.set_domain(form.DOMAIN); - if (!machine_creds.set_machine_account()) { - message("Failed to access domain join information!"); - return false; - } - vampire_ctx.machine_creds = machine_creds; - vampire_ctx.session_info = session_info; - if (!ctx.SamSyncLdb(vampire_ctx)) { - message("Migration of remote domain to Samba failed: " + vampire_ctx.error_string); - return false; - } - - return true; -} - -return 0; diff --git a/source4/scripting/libjs/samr.js b/source4/scripting/libjs/samr.js deleted file mode 100644 index 6e8c70af3c..0000000000 --- a/source4/scripting/libjs/samr.js +++ /dev/null @@ -1,170 +0,0 @@ -/* - samr rpc utility functions - Copyright Andrew Tridgell 2005 - released under the GNU GPL version 3 or later -*/ - -if (global["HAVE_SAMR_JS"] != undefined) { - return; -} -HAVE_SAMR_JS=1 - -/* - return a list of names and indexes from a samArray -*/ -function samArray(output) -{ - var list = new Array(output.num_entries); - if (output.sam == NULL) { - return list; - } - var i, entries = output.sam.entries; - for (i=0;i<output.num_entries;i++) { - list[i] = new Object(); - list[i].name = entries[i].name; - list[i].idx = entries[i].idx; - } - return list; -} - -/* - connect to the sam database -*/ -function samrConnect(conn) -{ - security_init(conn); - var io = irpcObj(); - io.input.system_name = NULL; - io.input.access_mask = conn.SEC_FLAG_MAXIMUM_ALLOWED; - var status = conn.samr_Connect2(io); - check_status_ok(status); - return io.output.connect_handle; -} - -/* - close a handle -*/ -function samrClose(conn, handle) -{ - var io = irpcObj(); - io.input.handle = handle; - var status = conn.samr_Close(io); - check_status_ok(status); -} - -/* - get the sid for a domain -*/ -function samrLookupDomain(conn, handle, domain) -{ - var io = irpcObj(); - io.input.connect_handle = handle; - io.input.domain_name = domain; - var status = conn.samr_LookupDomain(io); - check_status_ok(status); - return io.output.sid; -} - -/* - open a domain by sid -*/ -function samrOpenDomain(conn, handle, sid) -{ - var io = irpcObj(); - io.input.connect_handle = handle; - io.input.access_mask = conn.SEC_FLAG_MAXIMUM_ALLOWED; - io.input.sid = sid; - var status = conn.samr_OpenDomain(io); - check_status_ok(status); - return io.output.domain_handle; -} - -/* - open a user by rid -*/ -function samrOpenUser(conn, handle, rid) -{ - var io = irpcObj(); - io.input.domain_handle = handle; - io.input.access_mask = conn.SEC_FLAG_MAXIMUM_ALLOWED; - io.input.rid = rid; - var status = conn.samr_OpenUser(io); - check_status_ok(status); - return io.output.user_handle; -} - -/* - return a list of all users -*/ -function samrEnumDomainUsers(conn, dom_handle) -{ - var io = irpcObj(); - io.input.domain_handle = dom_handle; - io.input.resume_handle = 0; - io.input.acct_flags = 0; - io.input.max_size = -1; - var status = conn.samr_EnumDomainUsers(io); - check_status_ok(status); - return samArray(io.output); -} - -/* - return a list of all groups -*/ -function samrEnumDomainGroups(conn, dom_handle) -{ - var io = irpcObj(); - io.input.domain_handle = dom_handle; - io.input.resume_handle = 0; - io.input.acct_flags = 0; - io.input.max_size = -1; - var status = conn.samr_EnumDomainGroups(io); - check_status_ok(status); - return samArray(io.output); -} - -/* - return a list of domains -*/ -function samrEnumDomains(conn, handle) -{ - var io = irpcObj(); - io.input.connect_handle = handle; - io.input.resume_handle = 0; - io.input.buf_size = -1; - var status = conn.samr_EnumDomains(io); - check_status_ok(status); - return samArray(io.output); -} - -/* - return information about a user -*/ -function samrQueryUserInfo(conn, user_handle, level) -{ - var r, io = irpcObj(); - io.input.user_handle = user_handle; - io.input.level = level; - var status = conn.samr_QueryUserInfo(io); - check_status_ok(status); - return io.output.info.info3; -} - - -/* - fill a user array with user information from samrQueryUserInfo -*/ -function samrFillUserInfo(conn, dom_handle, users, level) -{ - var i; - for (i=0;i<users.length;i++) { - var r, user_handle, info; - user_handle = samrOpenUser(conn, dom_handle, users[i].idx); - info = samrQueryUserInfo(conn, user_handle, level); - info.name = users[i].name; - info.idx = users[i].idx; - users[i] = info; - samrClose(conn, user_handle); - } -} - diff --git a/source4/scripting/libjs/winreg.js b/source4/scripting/libjs/winreg.js deleted file mode 100644 index 9db415694d..0000000000 --- a/source4/scripting/libjs/winreg.js +++ /dev/null @@ -1,291 +0,0 @@ -/* - winreg rpc utility functions - Copyright Andrew Tridgell 2005 - released under the GNU GPL version 3 or later -*/ - -libinclude("base.js"); - -/* - close a handle -*/ -function __winreg_close(handle) -{ - var io = irpcObj(); - io.input.handle = handle; - this.winreg_CloseKey(io); -} - - -/* - open a hive -*/ -function __winreg_open_hive(hive) -{ - var io = irpcObj(); - io.input.system_name = NULL; - io.input.access_mask = this.SEC_FLAG_MAXIMUM_ALLOWED; - var status; - if (hive == "HKLM") { - status = this.winreg_OpenHKLM(io); - } else if (hive == "HKCR") { - status = this.winreg_OpenHKCR(io); - } else if (hive == "HKPD") { - status = this.winreg_OpenHKPD(io); - } else if (hive == "HKU") { - status = this.winreg_OpenHKU(io); - } else { - this._last_error = "Unknown hive " + hive; - return undefined; - } - if (!status.is_ok) { - return undefined; - } - return io.output.handle; -} - -/* - open a handle to a path -*/ -function __winreg_open_path(path) -{ - var s = string_init(); - var i, components = s.split('\\', path); - - /* cope with a leading slash */ - if (components[0] == '') { - for (i=0;i<(components.length-1);i++) { - components[i] = components[i+1]; - } - delete(components[i]); - } - - if (components.length == 0) { - return undefined; - } - - var handle = this.open_hive(components[0]); - if (handle == undefined) { - return undefined; - } - - if (components.length == 1) { - return handle; - } - - var hpath = components[1]; - - for (i=2;i<components.length;i++) { - hpath = hpath + "\\" + components[i]; - } - - io = irpcObj(); - io.input.parent_handle = handle; - io.input.keyname = hpath; - io.input.unknown = 0; - io.input.access_mask = this.SEC_FLAG_MAXIMUM_ALLOWED; - var status = this.winreg_OpenKey(io); - - this.close(handle); - - if (!status.is_ok) { - return undefined; - } - if (io.output.result != "WERR_OK") { - return undefined; - } - - return io.output.handle; -} - -/* - return a list of keys for a winreg server given a path - usage: - list = reg.enum_path(path); -*/ -function __winreg_enum_path(path) -{ - var list = new Array(0); - - if (path == null || path == "\\" || path == "") { - return new Array("HKLM", "HKU"); - } - - var handle = this.open_path(path); - if (handle == undefined) { - return undefined; - } - - var io = irpcObj(); - io.input.handle = handle; - io.input.name = new Object(); - io.input.name.length = 0; - io.input.name.size = 32; - io.input.name.name = NULL; - io.input.keyclass = new Object(); - io.input.keyclass.length = 0; - io.input.keyclass.size = 1024; - io.input.keyclass.name = NULL; - io.input.last_changed_time = 0; - - var idx = 0; - for (idx=0;idx >= 0;idx++) { - io.input.enum_index = idx; - var status = this.winreg_EnumKey(io); - if (!status.is_ok) { - this.close(handle); - return list; - } - var out = io.output; - if (out.result == "WERR_MORE_DATA") { - io.input.name.size = io.input.name.size * 2; - idx--; - if (io.input.name.size > 32000) { - this.close(handle); - return list; - } - continue; - } - if (out.result != "WERR_OK") { - this.close(handle); - return list; - } - list[list.length] = out.name.name; - } - - this.close(handle); - return list; -} - - -/* - return a list of values for a winreg server given a path - usage: - list = reg.enum_values(path); - - each returned list element is an object containing a name, a - type and a value -*/ -function __winreg_enum_values(path) -{ - var data = datablob_init(); - var list = new Array(0); - - var handle = this.open_path(path); - if (handle == undefined) { - return undefined; - } - - var io = irpcObj(); - io.input.handle = handle; - io.input.name = new Object(); - io.input.name.length = 0; - io.input.name.size = 128; - io.input.name.name = ""; - io.input.type = 0; - io.input.value = new Array(0); - io.input.size = 1024; - io.input.length = 0; - - var idx; - for (idx=0;idx >= 0;idx++) { - io.input.enum_index = idx; - var status = this.winreg_EnumValue(io); - if (!status.is_ok) { - this.close(handle); - return list; - } - var out = io.output; - if (out.result == "WERR_MORE_DATA") { - io.input.size = io.input.size * 2; - io.input.name.size = io.input.name.size * 2; - idx--; - /* limit blobs to 1M */ - if (io.input.size > 1000000) { - this.close(handle); - return list; - } - continue; - } - if (out.result != "WERR_OK") { - this.close(handle); - return list; - } - var el = new Object(); - el.name = out.name.name; - el.type = out.type; - el.rawvalue = out.value; - el.value = data.regToVar(el.rawvalue, el.type); - el.size = out.size; - list[list.length] = el; - } - - this.close(handle); - return list; -} - - -/* - create a new key - ok = reg.create_key(path, key); -*/ -function __winreg_create_key(path, key) -{ - var handle = this.open_path(path); - if (handle == undefined) { - return undefined; - } - - var io = irpcObj(); - io.input.handle = handle; - io.input.name = key; - io.input.keyclass = NULL; - io.input.options = 0; - io.input.access_mask = this.SEC_FLAG_MAXIMUM_ALLOWED; - io.input.secdesc = NULL; - io.input.action_taken = 0; - - var status = this.winreg_CreateKey(io); - this.close(handle); - if (!status.is_ok) { - return false; - } - if (io.output.result != "WERR_OK") { - return false; - } - this.close(io.output.new_handle); - return true; -} - - -/* - return a string for a winreg type -*/ -function __winreg_typestring(type) -{ - return this.typenames[type]; -} - -/* - initialise the winreg lib, returning an object -*/ -function winregObj() -{ - var reg = winreg_init(); - security_init(reg); - - reg.typenames = new Array("REG_NONE", "REG_SZ", "REG_EXPAND_SZ", "REG_BINARY", - "REG_DWORD", "REG_DWORD_BIG_ENDIAN", "REG_LINK", "REG_MULTI_SZ", - "REG_RESOURCE_LIST", "REG_FULL_RESOURCE_DESCRIPTOR", - "REG_RESOURCE_REQUIREMENTS_LIST", "REG_QWORD"); - - reg.close = __winreg_close; - reg.open_hive = __winreg_open_hive; - reg.open_path = __winreg_open_path; - reg.enum_path = __winreg_enum_path; - reg.enum_values = __winreg_enum_values; - reg.create_key = __winreg_create_key; - reg.typestring = __winreg_typestring; - - return reg; -} diff --git a/source4/scripting/python/config.m4 b/source4/scripting/python/config.m4 index 3790071ba8..b599aaefb0 100644 --- a/source4/scripting/python/config.m4 +++ b/source4/scripting/python/config.m4 @@ -5,7 +5,7 @@ AC_ARG_VAR([PYTHON_VERSION],[The installed Python will be appended to the Python interpreter canonical name.]) -AC_PROG_SWIG(1.3.31) +AC_PROG_SWIG(1.3.35) AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]]) if test -z "$PYTHON"; then @@ -64,10 +64,14 @@ SMB_EXT_LIB(EXT_LIB_PYTHON, [$PYTHON_LDFLAGS], [$PYTHON_CFLAGS]) AC_MSG_CHECKING(working python module support) if test $working_python = yes; then SMB_ENABLE(EXT_LIB_PYTHON,YES) - SMB_ENABLE(smbpython,YES) SMB_ENABLE(LIBPYTHON,YES) AC_MSG_RESULT([yes]) else AC_MSG_ERROR([Python not found. Please install Python 2.x and its development headers/libraries.]) fi +AC_MSG_CHECKING(python library directory) +pythondir=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_python_lib(1, 0, '\\${prefix}')"` +AC_MSG_RESULT($pythondir) + +AC_SUBST(pythondir) diff --git a/source4/scripting/python/config.mk b/source4/scripting/python/config.mk index 59f628fe18..b494ee6e8d 100644 --- a/source4/scripting/python/config.mk +++ b/source4/scripting/python/config.mk @@ -1,29 +1,37 @@ -[BINARY::smbpython] -PRIVATE_DEPENDENCIES = LIBPYTHON - -smbpython_OBJ_FILES = scripting/python/smbpython.o - [SUBSYSTEM::LIBPYTHON] PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON +PRIVATE_DEPENDENCIES = PYTALLOC INIT_FUNCTION_SENTINEL = { NULL, NULL } -LIBPYTHON_OBJ_FILES = $(addprefix scripting/python/, modules.o pytalloc.o) +LIBPYTHON_OBJ_FILES = $(addprefix $(pyscriptsrcdir)/, modules.o) + +[SUBSYSTEM::PYTALLOC] +PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON LIBTALLOC + +PYTALLOC_OBJ_FILES = $(addprefix $(pyscriptsrcdir)/, pytalloc.o) [PYTHON::python_uuid] PRIVATE_DEPENDENCIES = LIBNDR -python_uuid_OBJ_FILES = scripting/python/uuidmodule.o +python_uuid_OBJ_FILES = $(pyscriptsrcdir)/uuidmodule.o [PYTHON::python_misc] +LIBRARY_REALNAME = samba/_misc.$(SHLIBEXT) PRIVATE_DEPENDENCIES = LIBNDR LIBLDB SAMDB CREDENTIALS -SWIG_FILE = misc.i -python_misc_OBJ_FILES = scripting/python/misc_wrap.o +python_misc_OBJ_FILES = $(pyscriptsrcdir)/misc_wrap.o + +$(python_misc_OBJ_FILES): CFLAGS+=$(CFLAG_NO_UNUSED_MACROS) $(CFLAG_NO_CAST_QUAL) + +_PY_FILES = $(shell find $(pyscriptsrcdir)/samba $(pyscriptsrcdir)/subunit -name "*.py") + +$(foreach pyfile, $(_PY_FILES),$(eval $(call python_py_module_template,$(patsubst $(pyscriptsrcdir)/%,%,$(pyfile)),$(pyfile)))) + +$(eval $(call python_py_module_template,samba/misc.py,$(pyscriptsrcdir)/misc.py)) + +EPYDOC_OPTIONS = --no-private --url http://www.samba.org/ --no-sourcecode -PYDOCTOR_MODULES=bin/python/ldb.py bin/python/auth.py bin/python/credentials.py bin/python/registry.py bin/python/tdb.py bin/python/security.py bin/python/events.py bin/python/net.py +epydoc:: pythonmods + PYTHONPATH=$(pythonbuilddir) epydoc $(EPYDOC_OPTIONS) samba tdb ldb subunit -installpython:: pythonmods - @$(SHELL) $(srcdir)/script/installpython.sh \ - $(INSTALLPERMS) \ - $(DESTDIR)$(PYTHONDIR) \ - scripting/python bin/python +install:: installpython diff --git a/source4/scripting/python/misc.i b/source4/scripting/python/misc.i index 6fa3bc93e3..9a4c124121 100644 --- a/source4/scripting/python/misc.i +++ b/source4/scripting/python/misc.i @@ -40,6 +40,15 @@ %rename(random_password) generate_random_str; char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len); +%feature("docstring") ldb_set_credentials "S.set_credentials(credentials)\n" + "Set credentials to use when connecting."; + +%feature("docstring") ldb_set_session_info "S.set_session_info(session_info)\n" + "Set session info to use when connecting."; + +%feature("docstring") ldb_set_loadparm "S.set_loadparm(session_info)\n" + "Set loadparm context to use when connecting."; + %inline %{ void ldb_set_credentials(struct ldb_context *ldb, struct cli_credentials *creds) { @@ -58,14 +67,20 @@ void ldb_set_loadparm(struct ldb_context *ldb, struct loadparm_context *lp_ctx) %} +%feature("docstring") samdb_set_domain_sid "S.set_domain_sid(sid)\n" + "Set SID of domain to use."; bool samdb_set_domain_sid(struct ldb_context *ldb, const struct dom_sid *dom_sid_in); WERROR dsdb_attach_schema_from_ldif_file(struct ldb_context *ldb, const char *pf, const char *df); +%feature("docstring") samba_version_string "version()\n" + "Obtain the Samba version."; %rename(version) samba_version_string; const char *samba_version_string(void); int dsdb_set_global_schema(struct ldb_context *ldb); +%feature("docstring") ldb_register_samba_handlers "register_samba_handlers()\n" + "Register Samba-specific LDB modules and schemas."; int ldb_register_samba_handlers(struct ldb_context *ldb); %inline %{ diff --git a/source4/scripting/python/misc.py b/source4/scripting/python/misc.py index f1da4c687a..25e8d2de8c 100644 --- a/source4/scripting/python/misc.py +++ b/source4/scripting/python/misc.py @@ -1,5 +1,5 @@ # This file was automatically generated by SWIG (http://www.swig.org). -# Version 1.3.33 +# Version 1.3.35 # # Don't modify this file, modify the SWIG interface instead. @@ -62,14 +62,50 @@ import credentials import param import security random_password = _misc.random_password -ldb_set_credentials = _misc.ldb_set_credentials -ldb_set_session_info = _misc.ldb_set_session_info -ldb_set_loadparm = _misc.ldb_set_loadparm -samdb_set_domain_sid = _misc.samdb_set_domain_sid + +def ldb_set_credentials(*args, **kwargs): + """ + S.set_credentials(credentials) + Set credentials to use when connecting. + """ + return _misc.ldb_set_credentials(*args, **kwargs) + +def ldb_set_session_info(*args, **kwargs): + """ + S.set_session_info(session_info) + Set session info to use when connecting. + """ + return _misc.ldb_set_session_info(*args, **kwargs) + +def ldb_set_loadparm(*args, **kwargs): + """ + S.set_loadparm(session_info) + Set loadparm context to use when connecting. + """ + return _misc.ldb_set_loadparm(*args, **kwargs) + +def samdb_set_domain_sid(*args, **kwargs): + """ + S.set_domain_sid(sid) + Set SID of domain to use. + """ + return _misc.samdb_set_domain_sid(*args, **kwargs) dsdb_attach_schema_from_ldif_file = _misc.dsdb_attach_schema_from_ldif_file -version = _misc.version + +def version(*args): + """ + version() + Obtain the Samba version. + """ + return _misc.version(*args) dsdb_set_global_schema = _misc.dsdb_set_global_schema -ldb_register_samba_handlers = _misc.ldb_register_samba_handlers + +def ldb_register_samba_handlers(*args, **kwargs): + """ + register_samba_handlers() + Register Samba-specific LDB modules and schemas. + """ + return _misc.ldb_register_samba_handlers(*args, **kwargs) dsdb_set_ntds_invocation_id = _misc.dsdb_set_ntds_invocation_id private_path = _misc.private_path diff --git a/source4/scripting/python/misc_wrap.c b/source4/scripting/python/misc_wrap.c index 4944515d15..22a072fc6f 100644 --- a/source4/scripting/python/misc_wrap.c +++ b/source4/scripting/python/misc_wrap.c @@ -1,6 +1,6 @@ /* ---------------------------------------------------------------------------- * This file was automatically generated by SWIG (http://www.swig.org). - * Version 1.3.33 + * Version 1.3.35 * * This file is not intended to be easily readable and contains a number of * coding conventions designed to improve portability and efficiency. Do not make @@ -126,7 +126,7 @@ /* This should only be incremented when either the layout of swig_type_info changes, or for whatever reason, the runtime changes incompatibly */ -#define SWIG_RUNTIME_VERSION "3" +#define SWIG_RUNTIME_VERSION "4" /* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ #ifdef SWIG_TYPE_TABLE @@ -161,6 +161,7 @@ /* Flags for pointer conversions */ #define SWIG_POINTER_DISOWN 0x1 +#define SWIG_CAST_NEW_MEMORY 0x2 /* Flags for new pointer objects */ #define SWIG_POINTER_OWN 0x1 @@ -301,10 +302,10 @@ SWIGINTERNINLINE int SWIG_CheckState(int r) { extern "C" { #endif -typedef void *(*swig_converter_func)(void *); +typedef void *(*swig_converter_func)(void *, int *); typedef struct swig_type_info *(*swig_dycast_func)(void **); -/* Structure to store inforomation on one type */ +/* Structure to store information on one type */ typedef struct swig_type_info { const char *name; /* mangled name of this type */ const char *str; /* human readable name of this type */ @@ -431,8 +432,8 @@ SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { Cast a pointer up an inheritance hierarchy */ SWIGRUNTIMEINLINE void * -SWIG_TypeCast(swig_cast_info *ty, void *ptr) { - return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr); +SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); } /* @@ -856,7 +857,7 @@ SWIG_Python_AddErrorMsg(const char* mesg) Py_DECREF(old_str); Py_DECREF(value); } else { - PyErr_Format(PyExc_RuntimeError, mesg); + PyErr_SetString(PyExc_RuntimeError, mesg); } } @@ -1416,7 +1417,7 @@ PySwigObject_dealloc(PyObject *v) { PySwigObject *sobj = (PySwigObject *) v; PyObject *next = sobj->next; - if (sobj->own) { + if (sobj->own == SWIG_POINTER_OWN) { swig_type_info *ty = sobj->ty; PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; PyObject *destroy = data ? data->destroy : 0; @@ -1434,12 +1435,13 @@ PySwigObject_dealloc(PyObject *v) res = ((*meth)(mself, v)); } Py_XDECREF(res); - } else { - const char *name = SWIG_TypePrettyName(ty); + } #if !defined(SWIG_PYTHON_SILENT_MEMLEAK) - printf("swig/python detected a memory leak of type '%s', no destructor found.\n", name); -#endif + else { + const char *name = SWIG_TypePrettyName(ty); + printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown")); } +#endif } Py_XDECREF(next); PyObject_DEL(v); @@ -1944,7 +1946,7 @@ SWIG_Python_GetSwigThis(PyObject *pyobj) SWIGRUNTIME int SWIG_Python_AcquirePtr(PyObject *obj, int own) { - if (own) { + if (own == SWIG_POINTER_OWN) { PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); if (sobj) { int oldown = sobj->own; @@ -1965,6 +1967,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int return SWIG_OK; } else { PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); + if (own) + *own = 0; while (sobj) { void *vptr = sobj->ptr; if (ty) { @@ -1978,7 +1982,15 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int if (!tc) { sobj = (PySwigObject *)sobj->next; } else { - if (ptr) *ptr = SWIG_TypeCast(tc,vptr); + if (ptr) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + if (newmemory == SWIG_CAST_NEW_MEMORY) { + assert(own); + if (own) + *own = *own | SWIG_CAST_NEW_MEMORY; + } + } break; } } @@ -1988,7 +2000,8 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int } } if (sobj) { - if (own) *own = sobj->own; + if (own) + *own = *own | sobj->own; if (flags & SWIG_POINTER_DISOWN) { sobj->own = 0; } @@ -2053,8 +2066,13 @@ SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { } if (ty) { swig_cast_info *tc = SWIG_TypeCheck(desc,ty); - if (!tc) return SWIG_ERROR; - *ptr = SWIG_TypeCast(tc,vptr); + if (tc) { + int newmemory = 0; + *ptr = SWIG_TypeCast(tc,vptr,&newmemory); + assert(!newmemory); /* newmemory handling not yet implemented */ + } else { + return SWIG_ERROR; + } } else { *ptr = vptr; } @@ -2519,7 +2537,7 @@ static swig_module_info swig_module = {swig_types, 27, 0, 0, 0, 0}; #define SWIG_name "_misc" -#define SWIGVERSION 0x010333 +#define SWIGVERSION 0x010335 #define SWIG_VERSION SWIGVERSION @@ -3199,14 +3217,32 @@ fail: static PyMethodDef SwigMethods[] = { { (char *)"random_password", (PyCFunction) _wrap_random_password, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"ldb_set_credentials", (PyCFunction) _wrap_ldb_set_credentials, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"ldb_set_session_info", (PyCFunction) _wrap_ldb_set_session_info, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"ldb_set_loadparm", (PyCFunction) _wrap_ldb_set_loadparm, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"samdb_set_domain_sid", (PyCFunction) _wrap_samdb_set_domain_sid, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"ldb_set_credentials", (PyCFunction) _wrap_ldb_set_credentials, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.set_credentials(credentials)\n" + "Set credentials to use when connecting.\n" + ""}, + { (char *)"ldb_set_session_info", (PyCFunction) _wrap_ldb_set_session_info, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.set_session_info(session_info)\n" + "Set session info to use when connecting.\n" + ""}, + { (char *)"ldb_set_loadparm", (PyCFunction) _wrap_ldb_set_loadparm, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.set_loadparm(session_info)\n" + "Set loadparm context to use when connecting.\n" + ""}, + { (char *)"samdb_set_domain_sid", (PyCFunction) _wrap_samdb_set_domain_sid, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "S.set_domain_sid(sid)\n" + "Set SID of domain to use.\n" + ""}, { (char *)"dsdb_attach_schema_from_ldif_file", (PyCFunction) _wrap_dsdb_attach_schema_from_ldif_file, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"version", (PyCFunction)_wrap_version, METH_NOARGS, NULL}, + { (char *)"version", (PyCFunction)_wrap_version, METH_NOARGS, (char *)"\n" + "version()\n" + "Obtain the Samba version.\n" + ""}, { (char *)"dsdb_set_global_schema", (PyCFunction) _wrap_dsdb_set_global_schema, METH_VARARGS | METH_KEYWORDS, NULL}, - { (char *)"ldb_register_samba_handlers", (PyCFunction) _wrap_ldb_register_samba_handlers, METH_VARARGS | METH_KEYWORDS, NULL}, + { (char *)"ldb_register_samba_handlers", (PyCFunction) _wrap_ldb_register_samba_handlers, METH_VARARGS | METH_KEYWORDS, (char *)"\n" + "register_samba_handlers()\n" + "Register Samba-specific LDB modules and schemas.\n" + ""}, { (char *)"dsdb_set_ntds_invocation_id", (PyCFunction) _wrap_dsdb_set_ntds_invocation_id, METH_VARARGS | METH_KEYWORDS, NULL}, { (char *)"private_path", (PyCFunction) _wrap_private_path, METH_VARARGS | METH_KEYWORDS, NULL}, { NULL, NULL, 0, NULL } @@ -3225,7 +3261,7 @@ static swig_type_info _swigt__p_ldb_context = {"_p_ldb_context", "struct ldb_con static swig_type_info _swigt__p_ldb_dn = {"_p_ldb_dn", "struct ldb_dn *|ldb_dn *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_ldb_ldif = {"_p_ldb_ldif", "struct ldb_ldif *|ldb_ldif *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_ldb_message = {"_p_ldb_message", "ldb_msg *|struct ldb_message *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_ldb_message_element = {"_p_ldb_message_element", "struct ldb_message_element *|ldb_msg_element *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_ldb_message_element = {"_p_ldb_message_element", "struct ldb_message_element *|ldb_message_element *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_ldb_result = {"_p_ldb_result", "struct ldb_result *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_loadparm_context = {"_p_loadparm_context", "struct loadparm_context *|loadparm_context *", 0, 0, (void*)0, 0}; static swig_type_info _swigt__p_loadparm_service = {"_p_loadparm_service", "struct loadparm_service *|loadparm_service *", 0, 0, (void*)0, 0}; @@ -3397,7 +3433,7 @@ SWIGRUNTIME void SWIG_InitializeModule(void *clientdata) { size_t i; swig_module_info *module_head, *iter; - int found; + int found, init; clientdata = clientdata; @@ -3407,6 +3443,9 @@ SWIG_InitializeModule(void *clientdata) { swig_module.type_initial = swig_type_initial; swig_module.cast_initial = swig_cast_initial; swig_module.next = &swig_module; + init = 1; + } else { + init = 0; } /* Try and load any already created modules */ @@ -3435,6 +3474,12 @@ SWIG_InitializeModule(void *clientdata) { module_head->next = &swig_module; } + /* When multiple interpeters are used, a module could have already been initialized in + a different interpreter, but not yet have a pointer in this interpreter. + In this case, we do not want to continue adding types... everything should be + set up already */ + if (init == 0) return; + /* Now work on filling in swig_module.types */ #ifdef SWIGRUNTIME_DEBUG printf("SWIG_InitializeModule: size %d\n", swig_module.size); diff --git a/source4/scripting/python/modules.c b/source4/scripting/python/modules.c index 6cd975c1a9..0fe15b2fda 100644 --- a/source4/scripting/python/modules.c +++ b/source4/scripting/python/modules.c @@ -19,7 +19,6 @@ #include "includes.h" #include <Python.h> -#include "build.h" extern void init_ldb(void); extern void init_security(void); @@ -40,12 +39,10 @@ extern void initdrsuapi(void); extern void initwinreg(void); extern void initepmapper(void); extern void initinitshutdown(void); -static void initdcerpc_misc(void) {} extern void initmgmt(void); extern void initnet(void); extern void initatsvc(void); extern void initsamr(void); -static void initdcerpc_security(void) {} extern void initlsa(void); extern void initsvcctl(void); extern void initwkssvc(void); diff --git a/source4/scripting/python/pyrpc.h b/source4/scripting/python/pyrpc.h index f4d0f37c39..93d583c10a 100644 --- a/source4/scripting/python/pyrpc.h +++ b/source4/scripting/python/pyrpc.h @@ -17,6 +17,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#ifndef _PYRPC_H_ +#define _PYRPC_H_ + #define PY_CHECK_TYPE(type, var, fail) \ if (!type ## _Check(var)) {\ PyErr_Format(PyExc_TypeError, "Expected type %s", type ## _Type.tp_name); \ @@ -32,3 +35,5 @@ #ifndef PyAPI_DATA # define PyAPI_DATA(RTYPE) extern RTYPE #endif + +#endif /* _PYRPC_H_ */ diff --git a/source4/scripting/python/pytalloc.c b/source4/scripting/python/pytalloc.c index aa0ae9bf90..ca476e9604 100644 --- a/source4/scripting/python/pytalloc.c +++ b/source4/scripting/python/pytalloc.c @@ -24,6 +24,7 @@ void py_talloc_dealloc(PyObject* self) { py_talloc_Object *obj = (py_talloc_Object *)self; talloc_free(obj->talloc_ctx); + obj->talloc_ctx = NULL; PyObject_Del(self); } @@ -31,7 +32,13 @@ PyObject *py_talloc_import_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr) { py_talloc_Object *ret = PyObject_New(py_talloc_Object, py_type); - ret->talloc_ctx = talloc_reference(NULL, mem_ctx); + ret->talloc_ctx = talloc_new(NULL); + if (ret->talloc_ctx == NULL) { + return NULL; + } + if (talloc_reference(ret->talloc_ctx, mem_ctx) == NULL) { + return NULL; + } ret->ptr = ptr; return (PyObject *)ret; } @@ -41,5 +48,5 @@ PyObject *py_talloc_default_repr(PyObject *py_obj) py_talloc_Object *obj = (py_talloc_Object *)py_obj; PyTypeObject *type = (PyTypeObject*)PyObject_Type((PyObject *)obj); - return PyString_FromFormat("<%s>", type->tp_name); + return PyString_FromFormat("<%s talloc object at 0x%x>", type->tp_name, (intptr_t)py_obj); } diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index b9d81c6c3c..94f9e4d005 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -20,6 +20,8 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # +__docformat__ = "restructuredText" + import os def _in_source_tree(): @@ -33,6 +35,8 @@ if _in_source_tree(): srcdir = "%s/../../.." % os.path.dirname(__file__) sys.path.append("%s/bin/python" % srcdir) default_ldb_modules_dir = "%s/bin/modules/ldb" % srcdir +else: + default_ldb_modules_dir = None import ldb @@ -69,15 +73,15 @@ class Ldb(ldb.Ldb): self.set_modules_dir(default_ldb_modules_dir) if credentials is not None: - self.set_credentials(self, credentials) + self.set_credentials(credentials) if session_info is not None: - self.set_session_info(self, session_info) + self.set_session_info(session_info) assert misc.ldb_register_samba_handlers(self) == 0 if lp is not None: - self.set_loadparm(self, lp) + self.set_loadparm(lp) def msg(l,text): print text diff --git a/source4/scripting/python/samba/getopt.py b/source4/scripting/python/samba/getopt.py index 7ec684a9d6..9ecb66e21c 100644 --- a/source4/scripting/python/samba/getopt.py +++ b/source4/scripting/python/samba/getopt.py @@ -17,10 +17,15 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # +"""Support for parsing Samba-related command-line options.""" + import optparse from credentials import Credentials, AUTO_USE_KERBEROS, DONT_USE_KERBEROS, MUST_USE_KERBEROS +__docformat__ = "restructuredText" + class SambaOptions(optparse.OptionGroup): + """General Samba-related command line options.""" def __init__(self, parser): optparse.OptionGroup.__init__(self, parser, "Samba Common Options") self.add_option("-s", "--configfile", action="callback", @@ -29,12 +34,14 @@ class SambaOptions(optparse.OptionGroup): self._configfile = None def get_loadparm_path(self): + """Return the path to the smb.conf file specified on the command line. """ return self._configfile def _load_configfile(self, option, opt_str, arg, parser): self._configfile = arg def get_loadparm(self): + """Return a loadparm object with data specified on the command line. """ import os, param lp = param.LoadParm() if self._configfile is not None: @@ -45,12 +52,15 @@ class SambaOptions(optparse.OptionGroup): lp.load_default() return lp + class VersionOptions(optparse.OptionGroup): + """Command line option for printing Samba version.""" def __init__(self, parser): optparse.OptionGroup.__init__(self, parser, "Version Options") class CredentialsOptions(optparse.OptionGroup): + """Command line options for specifying credentials.""" def __init__(self, parser): self.no_pass = False optparse.OptionGroup.__init__(self, parser, "Credentials Options") @@ -91,6 +101,11 @@ class CredentialsOptions(optparse.OptionGroup): self.creds.set_bind_dn(arg) def get_credentials(self, lp): + """Obtain the credentials set on the command-line. + + :param lp: Loadparm object to use. + :return: Credentials object + """ self.creds.guess(lp) if not self.no_pass: self.creds.set_cmdline_callbacks() diff --git a/source4/scripting/python/samba/idmap.py b/source4/scripting/python/samba/idmap.py index 16efcd0470..755ec52c7b 100644 --- a/source4/scripting/python/samba/idmap.py +++ b/source4/scripting/python/samba/idmap.py @@ -20,6 +20,8 @@ """Convenience functions for using the idmap database.""" +__docformat__ = "restructuredText" + import samba import misc import ldb diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 0e8840646c..68b43eff40 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -43,6 +43,8 @@ from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ """Functions for setting up a Samba configuration.""" +__docformat__ = "restructuredText" + DEFAULTSITE = "Default-First-Site-Name" class InvalidNetbiosName(Exception): @@ -236,6 +238,8 @@ def provision_paths_from_lp(lp, dnsdomain): paths.secrets = os.path.join(paths.private_dir, lp.get("secrets database") or "secrets.ldb") paths.templates = os.path.join(paths.private_dir, "templates.ldb") paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone") + paths.namedconf = os.path.join(paths.private_dir, "named.conf") + paths.krb5conf = os.path.join(paths.private_dir, "krb5.conf") paths.winsdb = os.path.join(paths.private_dir, "wins.ldb") paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi") paths.phpldapadminconfig = os.path.join(paths.private_dir, @@ -689,6 +693,7 @@ def setup_self_join(samdb, names, domainsid, invocationid, setup_path, policyguid): """Join a host to its own domain.""" + assert isinstance(invocationid, str) setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), { "CONFIGDN": names.configdn, "SCHEMADN": names.schemadn, @@ -910,7 +915,7 @@ def provision(setup_dir, message, session_info, domainsid = security.Sid(domainsid) if policyguid is None: - policyguid = uuid.random() + policyguid = str(uuid.uuid4()) if adminpass is None: adminpass = misc.random_password(12) if krbtgtpass is None: @@ -960,7 +965,7 @@ def provision(setup_dir, message, session_info, assert serverrole in ("domain controller", "member server", "standalone") if invocationid is None and serverrole == "domain controller": - invocationid = uuid.random() + invocationid = str(uuid.uuid4()) if not os.path.exists(paths.private_dir): os.mkdir(paths.private_dir) @@ -1057,14 +1062,23 @@ def provision(setup_dir, message, session_info, expression="(&(objectClass=computer)(cn=%s))" % names.hostname, scope=SCOPE_SUBTREE) assert isinstance(hostguid, str) - - create_zone_file(paths.dns, setup_path, samdb, - hostname=names.hostname, hostip=hostip, - hostip6=hostip6, dnsdomain=names.dnsdomain, - domaindn=names.domaindn, dnspass=dnspass, realm=names.realm, + + create_zone_file(paths.dns, setup_path, dnsdomain=names.dnsdomain, + domaindn=names.domaindn, hostip=hostip, + hostip6=hostip6, hostname=names.hostname, + dnspass=dnspass, realm=names.realm, domainguid=domainguid, hostguid=hostguid) message("Please install the zone located in %s into your DNS server" % paths.dns) - + + create_named_conf(paths.namedconf, setup_path, realm=names.realm, + dnsdomain=names.dnsdomain, private_dir=paths.private_dir, + keytab_name=paths.dns_keytab) + message("See %s for example configuration statements for secure GSS-TSIG updates" % paths.namedconf) + + create_krb5_conf(paths.krb5conf, setup_path, dnsdomain=names.dnsdomain, + hostname=names.hostname, realm=names.realm) + message("A Kerberos configuration suitable for Samba 4 has been generated at %s" % paths.krb5conf) + create_phpldapadmin_config(paths.phpldapadminconfig, setup_path, ldapi_url) @@ -1280,13 +1294,12 @@ def create_phpldapadmin_config(path, setup_path, ldapi_uri): {"S4_LDAPI_URI": ldapi_uri}) -def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, - hostip, hostip6, hostname, dnspass, realm, domainguid, hostguid): +def create_zone_file(path, setup_path, dnsdomain, domaindn, + hostip, hostip6, hostname, dnspass, realm, domainguid, hostguid): """Write out a DNS zone file, from the info in the current database. - - :param path: Path of the new file. - :param setup_path": Setup path function. - :param samdb: SamDB object + + :param path: Path of the new zone file. + :param setup_path: Setup path function. :param dnsdomain: DNS Domain name :param domaindn: DN of the Domain :param hostip: Local IPv4 IP @@ -1320,6 +1333,44 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, "HOSTIP6_HOST_LINE": hostip6_host_line, }) +def create_named_conf(path, setup_path, realm, dnsdomain, + private_dir, keytab_name): + """Write out a file containing zone statements suitable for inclusion in a + named.conf file (including GSS-TSIG configuration). + + :param path: Path of the new named.conf file. + :param setup_path: Setup path function. + :param realm: Realm name + :param dnsdomain: DNS Domain name + :param private_dir: Path to private directory + :param keytab_name: File name of DNS keytab file + """ + + setup_file(setup_path("named.conf"), path, { + "DNSDOMAIN": dnsdomain, + "REALM": realm, + "REALM_WC": "*." + ".".join(realm.split(".")[1:]), + "DNS_KEYTAB": keytab_name, + "DNS_KEYTAB_ABS": os.path.join(private_dir, keytab_name), + }) + +def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm): + """Write out a file containing zone statements suitable for inclusion in a + named.conf file (including GSS-TSIG configuration). + + :param path: Path of the new named.conf file. + :param setup_path: Setup path function. + :param dnsdomain: DNS Domain name + :param hostname: Local hostname + :param realm: Realm name + """ + + setup_file(setup_path("krb5.conf"), path, { + "DNSDOMAIN": dnsdomain, + "HOSTNAME": hostname, + "REALM": realm, + }) + def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): """Load schema for the SamDB. diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index cffedb54af..c1340b7760 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -19,6 +19,8 @@ """Support for reading Samba 3 data files.""" +__docformat__ = "restructuredText" + REGISTRY_VALUE_PREFIX = "SAMBA_REGVAL" REGISTRY_DB_VERSION = 1 @@ -307,6 +309,7 @@ class ShareInfoDatabase(TdbDatabase): class Shares: + """Container for share objects.""" def __init__(self, lp, shareinfo): self.lp = lp self.shareinfo = shareinfo @@ -492,6 +495,7 @@ class TdbSam(TdbDatabase): assert self.version in (0, 1, 2) def usernames(self): + """Iterate over the usernames in this Tdb database.""" for k in self.tdb.keys(): if k.startswith(TDBSAM_USER_PREFIX): yield k[len(TDBSAM_USER_PREFIX):].rstrip("\0") @@ -633,6 +637,7 @@ class WinsDatabase: return iter(self.entries) def items(self): + """Return the entries in this WINS database.""" return self.entries.items() def close(self): # for consistency diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 198d1e9f5c..6465f49519 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -28,6 +28,8 @@ import ldb from samba.idmap import IDmapDB import pwd +__docformat__ = "restructuredText" + class SamDB(samba.Ldb): """The SAM database.""" diff --git a/source4/scripting/python/samba/tests/dcerpc/registry.py b/source4/scripting/python/samba/tests/dcerpc/registry.py index 1afdc582a7..81133ff641 100644 --- a/source4/scripting/python/samba/tests/dcerpc/registry.py +++ b/source4/scripting/python/samba/tests/dcerpc/registry.py @@ -17,7 +17,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -import winreg +from samba.dcerpc import winreg import unittest from samba.tests import RpcInterfaceTestCase diff --git a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py index 6c43632d97..3b37f8a9bc 100644 --- a/source4/scripting/python/samba/tests/dcerpc/rpcecho.py +++ b/source4/scripting/python/samba/tests/dcerpc/rpcecho.py @@ -17,7 +17,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -import echo +from samba.dcerpc import echo import unittest from samba.tests import RpcInterfaceTestCase diff --git a/source4/scripting/python/samba/tests/dcerpc/sam.py b/source4/scripting/python/samba/tests/dcerpc/sam.py index 8ef12dad86..50e00a3f9e 100644 --- a/source4/scripting/python/samba/tests/dcerpc/sam.py +++ b/source4/scripting/python/samba/tests/dcerpc/sam.py @@ -1,7 +1,8 @@ #!/usr/bin/python +# -*- coding: utf-8 -*- # Unix SMB/CIFS implementation. -# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008 +# Copyright © Jelmer Vernooij <jelmer@samba.org> 2008 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -17,12 +18,29 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -import samr +from samba.dcerpc import samr, security from samba.tests import RpcInterfaceTestCase +# FIXME: Pidl should be doing this for us +def toArray((handle, array, num_entries)): + ret = [] + for x in range(num_entries): + ret.append((array.entries[x].idx, array.entries[x].name)) + return ret + + class SamrTests(RpcInterfaceTestCase): def setUp(self): self.conn = samr.samr("ncalrpc:", self.get_loadparm()) def test_connect5(self): (level, info, handle) = self.conn.Connect5(None, 0, 1, samr.ConnectInfo1()) + + def test_connect2(self): + handle = self.conn.Connect2(None, security.SEC_FLAG_MAXIMUM_ALLOWED) + + def test_EnumDomains(self): + handle = self.conn.Connect2(None, security.SEC_FLAG_MAXIMUM_ALLOWED) + domains = toArray(self.conn.EnumDomains(handle, 0, -1)) + self.conn.Close(handle) + diff --git a/source4/scripting/python/samba/tests/dcerpc/unix.py b/source4/scripting/python/samba/tests/dcerpc/unix.py index 43978ac9dc..aa47b71b16 100644 --- a/source4/scripting/python/samba/tests/dcerpc/unix.py +++ b/source4/scripting/python/samba/tests/dcerpc/unix.py @@ -17,7 +17,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -import unixinfo +from samba.dcerpc import unixinfo from samba.tests import RpcInterfaceTestCase class UnixinfoTests(RpcInterfaceTestCase): @@ -27,8 +27,8 @@ class UnixinfoTests(RpcInterfaceTestCase): def test_getpwuid(self): infos = self.conn.GetPWUid(range(512)) self.assertEquals(512, len(infos)) - self.assertEquals("", infos[0].shell) - self.assertEquals("", infos[0].homedir) + self.assertEquals("/bin/false", infos[0].shell) + self.assertTrue(isinstance(infos[0].homedir, unicode)) def test_gidtosid(self): self.conn.GidToSid(1000) diff --git a/source4/scripting/python/samba/tests/provision.py b/source4/scripting/python/samba/tests/provision.py index b9e0e16d3c..76c10145f0 100644 --- a/source4/scripting/python/samba/tests/provision.py +++ b/source4/scripting/python/samba/tests/provision.py @@ -21,7 +21,7 @@ import os from samba.provision import setup_secretsdb, secretsdb_become_dc, findnss import samba.tests from ldb import Dn -import param +from samba import param import unittest lp = samba.tests.cmdline_loadparm diff --git a/source4/scripting/python/samba/tests/samdb.py b/source4/scripting/python/samba/tests/samdb.py index 0e175bf936..0d4f7bde0e 100644 --- a/source4/scripting/python/samba/tests/samdb.py +++ b/source4/scripting/python/samba/tests/samdb.py @@ -29,18 +29,18 @@ import uuid class SamDBTestCase(TestCaseInTempDir): def setUp(self): super(SamDBTestCase, self).setUp() - invocationid = uuid.random() + invocationid = str(uuid.uuid4()) domaindn = "DC=COM,DC=EXAMPLE" self.domaindn = domaindn configdn = "CN=Configuration," + domaindn schemadn = "CN=Schema," + configdn - domainguid = uuid.random() - policyguid = uuid.random() + domainguid = str(uuid.uuid4()) + policyguid = str(uuid.uuid4()) setup_path = lambda x: os.path.join("setup", x) creds = Credentials() creds.set_anonymous() domainsid = security.random_sid() - hostguid = uuid.random() + hostguid = str(uuid.uuid4()) path = os.path.join(self.tempdir, "samdb.ldb") self.samdb = setup_samdb(path, setup_path, system_session(), creds, cmdline_loadparm, schemadn, configdn, diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index f40f2cffe7..0c83604e82 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -7,6 +7,8 @@ """Support code for upgrading from Samba 3 to Samba 4.""" +__docformat__ = "restructuredText" + from provision import findnss, provision, FILL_DRS import grp import ldb diff --git a/source4/scripting/python/smbpython.c b/source4/scripting/python/smbpython.c deleted file mode 100644 index c5de53fd60..0000000000 --- a/source4/scripting/python/smbpython.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba utility functions - Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include <Python.h> -#include "scripting/python/modules.h" - -int main(int argc, char **argv) -{ - py_load_samba_modules(); - Py_Initialize(); - if (strchr(argv[0], '/') != NULL) { - char *bindir = strndup(argv[0], strrchr(argv[0], '/')-argv[0]); - py_update_path(bindir); - free(bindir); - } - return Py_Main(argc,argv); -} diff --git a/source4/scripting/python/uuidmodule.c b/source4/scripting/python/uuidmodule.c index 18cfb6ce32..98ef9adaa9 100644 --- a/source4/scripting/python/uuidmodule.c +++ b/source4/scripting/python/uuidmodule.c @@ -46,7 +46,7 @@ static PyObject *uuid_random(PyObject *self, PyObject *args) } static PyMethodDef methods[] = { - { "random", (PyCFunction)uuid_random, METH_VARARGS, NULL}, + { "uuid4", (PyCFunction)uuid_random, METH_VARARGS, NULL}, { NULL, NULL } }; |