wmi-1.3.16 from opsview.com

This commit is contained in:
Are Casilla
2019-02-16 00:16:52 +01:00
parent 163fdd3d1b
commit 17b3af2911
2146 changed files with 678824 additions and 0 deletions
+234
View File
@@ -0,0 +1,234 @@
#!/bin/sh
exec smbscript "$0" ${1+"$@"}
/*
Dump Samba3 data
Copyright Jelmer Vernooij 2005
Released under the GNU GPL v2 or later
*/
options = GetOptions(ARGV,
"POPT_AUTOHELP",
"POPT_COMMON_SAMBA",
"POPT_COMMON_VERSION",
'format=s',
'quiet', 'blank');
if (options == undefined) {
println("Failed to parse options");
return -1;
}
if (options.format == undefined) {
options.format = "summary";
}
if (options.format != "summary" && options.format != "full") {
printf("Unknown format %s\n", options.format);
return -1;
}
libinclude("base.js");
if (options.ARGV.length != 2) {
println("Usage: samba3dump <libdir> <smb.conf>");
return -1;
}
function print_header(txt)
{
printf("\n%s\n", txt);
println("==========================================");
}
function print_samba3_policy(pol)
{
print_header("Account Policies");
printf("Min password length: %d\n", pol.min_password_length);
printf("Password history length: %d\n", pol.password_history);
printf("User must logon to change password: %d\n", pol.user_must_logon_to_change_password);
printf("Maximum password age: %d\n", pol.maximum_password_age);
printf("Minimum password age: %d\n", pol.minimum_password_age);
printf("Lockout duration: %d\n", pol.lockout_duration);
printf("Reset Count Minutes: %d\n", pol.reset_count_minutes);
printf("Bad Lockout Minutes: %d\n", pol.bad_lockout_minutes);
printf("Disconnect Time: %d\n", pol.disconnect_time);
printf("Refuse Machine Password Change: %d\n", pol.refuse_machine_password_change);
}
function print_samba3_sam(samba3)
{
var i;
print_header("SAM Database");
for (i in samba3.samaccounts) {
var a = samba3.samaccounts[i];
printf("%d: %s\n", a.user_rid, a.username);
}
}
function print_samba3_shares(samba3)
{
var i, j;
print_header("Configured shares");
for (i in samba3.shares) {
var s = samba3.shares[i];
printf("--- %s ---\n", s.name);
for (j in s.parameters) {
var p = s.parameters[j];
printf("\t%s = %s\n", p.name, p.value);
}
println("");
}
}
function print_samba3_secrets(secrets)
{
var i;
print_header("Secrets");
println("IPC Credentials:");
if (secrets.ipc_cred.username_obtained)
printf(" User: %s\n", secrets.ipc_cred.get_username);
if (secrets.ipc_cred.password_obtained)
printf(" Password: %s\n", secrets.ipc_cred.get_password);
if (secrets.ipc_cred.domain_obtained)
printf(" Domain: %s\n\n", secrets.ipc_cred.get_domain);
println("LDAP passwords:");
for (i in secrets.ldappws) {
var pw = secrets.ldappws[i];
printf("\t%s -> %s\n", pw.dn, pw.password);
}
println("");
println("Domains:");
for (i in secrets.domains) {
var d = secrets.domains[i];
printf("\t--- %s ---\n", d.name);
printf("\tSID: %s\n", d.sid);
printf("\tGUID: %s\n", d.guid);
printf("\tPlaintext pwd: %s\n", d.plaintext_pw);
printf("\tLast Changed: %lu\n", d.last_change_time);
printf("\tSecure Channel Type: %d\n\n", d.sec_channel_type);
}
println("Trusted domains:");
for (i in secrets.trusted_domains) {
var td = secrets.trusted_domains[i];
for (j = 0; j < td.uni_name_len; j++) {
printf("\t--- %s ---\n", td.uni_name[j]);
}
printf("\tPassword: %s\n", td.pass);
printf("\tModified: %lu\n", td.mod_time);
printf("\tSID: %s\n", td.domain_sid);
}
}
function print_samba3_regdb(regdb)
{
var i, j;
print_header("Registry");
for (i in regdb.keys) {
var k = regdb.keys[i];
printf("%s\n", k.name);
for (j in k.values) {
var v = k.values[j];
printf("\t%s: type %d, length %d\n", v.name, v.type, v.data.length);
}
}
}
function print_samba3_winsdb(samba3)
{
var i;
print_header("WINS Database");
for (i in samba3.winsentries) {
var e = samba3.winsentries[i];
printf("%s, nb_flags: %x, type: %d, ttl: %lu, %d ips, fst: %s\n", e.name, e.nb_flags, e.type, e.ttl, e.ips.length, e.ips[0]);
}
}
function print_samba3_groupmappings(groupdb)
{
print_header("Group Mappings");
for (var i in groupdb.groupmappings) {
var g = groupdb.groupmappings[i];
printf("\t--- Group: %s ---\n", g.nt_name);
printf("\tComment: %s\n", g.comment);
printf("\tGID: %d\n", g.gid);
printf("\tSID Name Use: %d\n", g.sid_name_use);
printf("\tSID: %s\n\n", g.sid);
}
}
function print_samba3_aliases(groupdb)
{
var i, j;
for (i in groupdb.aliases) {
var a = groupdb.aliases[i];
printf("\t--- Alias: %s ---\n", a.sid);
for (j in a.members) {
printf("\t%s\n", a.members[j]);
}
}
}
function print_samba3_idmapdb(idmapdb)
{
var i;
print_header("Winbindd SID<->GID/UID mappings");
printf("User High Water Mark: %d\n", idmapdb.user_hwm);
printf("Group High Water Mark: %d\n\n", idmapdb.group_hwm);
for (i in idmapdb.mappings) {
var e = idmapdb.mappings[i];
printf("%s -> ", e.sid);
if (e.type == e.IDMAP_GROUP) {
printf("GID %d\n", e.unix_id);
} else {
printf("UID %d\n", e.unix_id);
}
}
}
function print_samba3(samba3)
{
print_samba3_sam(samba3);
print_samba3_policy(samba3.policy);
print_samba3_shares(samba3);
print_samba3_winsdb(samba3);
print_samba3_regdb(samba3.registry);
print_samba3_secrets(samba3.secrets);
print_samba3_groupmappings(samba3);
print_samba3_aliases(samba3);
print_samba3_idmapdb(samba3.idmapdb);
}
function print_samba3_summary(samba3)
{
printf("WINS db entries: %d\n", samba3.winsentries.length);
printf("SAM Accounts: %d\n", samba3.samaccounts.length);
printf("Registry key count: %d\n", samba3.registry.keys.length);
printf("Shares (including [global]): %d\n", samba3.shares.length);
printf("Groupmap count: %d\n", samba3.groupmappings.length);
printf("Alias count: %d\n", samba3.aliases.length);
printf("Idmap count: %d\n", samba3.idmapdb.mappings.length);
}
samba3 = samba3_read(options.ARGV[0], options.ARGV[1]);
if (options.format == "summary") {
print_samba3_summary(samba3);
} else if (options.format == "full") {
print_samba3(samba3);
}
return 0;
+96
View File
@@ -0,0 +1,96 @@
#!/bin/sh
exec smbscript "$0" ${1+"$@"}
/*
provide information on connected users and open files
Copyright Andrew Tridgell 2005
Released under the GNU GPL v2 or later
*/
libinclude("base.js");
libinclude("management.js");
var options = new Object();
options = GetOptions(ARGV,
"POPT_AUTOHELP",
"POPT_COMMON_SAMBA",
"POPT_COMMON_VERSION",
"nbt");
if (options == undefined) {
println("Failed to parse options: " + options.ERROR);
return -1;
}
/*
show open sessions
*/
function show_sessions()
{
var sessions = smbsrv_sessions();
var i;
var sys = sys_init();
if (sessions == undefined) {
println("No sessions open");
return;
}
printf("User Client Connected at\n");
printf("-------------------------------------------------------------------------------\n");
for (i=0;i<sessions.length;i++) {
var info = sessions[i];
var fulluser = sprintf("%s/%s", info.account_name, info.domain_name);
printf("%-30s %16s %s\n",
fulluser, info.client_ip, sys.httptime(info.connect_time));
}
printf("\n");
}
/*
show open tree connects
*/
function show_tcons()
{
var tcons = smbsrv_tcons();
var sys = sys_init();
if (tcons == undefined) {
println("No tree connects");
return;
}
printf("Share Client Connected at\n");
printf("-------------------------------------------------------------------------------\n");
for (i=0;i<tcons.length;i++) {
var info = tcons[i];
printf("%-30s %16s %s\n",
info.share_name, info.client_ip, sys.httptime(info.connect_time));
}
}
/*
show nbtd information
*/
function show_nbt()
{
var stats = nbtd_statistics();
if (stats == undefined) {
println("nbt server not running");
return;
}
var r;
println("NBT server statistics:");
for (r in stats) {
print("\t" + r + ":\t" + stats[r] + "\n");
}
println("");
}
var lp = loadparm_init();
printf("%s\n\n", lp.get("server string"));
if (options['nbt'] != undefined) {
show_nbt();
} else {
show_sessions();
show_tcons();
}
return 0;
+107
View File
@@ -0,0 +1,107 @@
#!/bin/sh
exec smbscript "$0" ${1+"$@"}
/*
tool to manipulate a remote registry
Copyright Andrew Tridgell 2005
Released under the GNU GPL v2 or later
*/
var options = GetOptions(ARGV,
"POPT_AUTOHELP",
"POPT_COMMON_SAMBA",
"POPT_COMMON_CREDENTIALS",
"createkey=s");
if (options == undefined) {
println("Failed to parse options");
return -1;
}
libinclude("base.js");
libinclude("winreg.js");
if (options.ARGV.length < 1) {
println("Usage: winreg.js <BINDING> [path]");
return -1;
}
var binding = options.ARGV[0];
reg = winregObj();
print("Connecting to " + binding + "\n");
status = reg.connect(binding);
if (status.is_ok != true) {
print("Failed to connect to " + binding + " - " + status.errstr + "\n");
return -1;
}
function list_values(path) {
var list = reg.enum_values(path);
var i;
if (list == undefined) {
return;
}
for (i=0;i<list.length;i++) {
var v = list[i];
printf("\ttype=%-30s size=%4d '%s'\n", reg.typestring(v.type), v.size, v.name);
if (v.type == reg.REG_SZ || v.type == reg.REG_EXPAND_SZ) {
printf("\t\t'%s'\n", v.value);
}
if (v.type == reg.REG_MULTI_SZ) {
var j;
for (j in v.value) {
printf("\t\t'%s'\n", v.value[j]);
}
}
if (v.type == reg.REG_DWORD || v.type == reg.REG_DWORD_BIG_ENDIAN) {
printf("\t\t0x%08x (%d)\n", v.value, v.value);
}
if (v.type == reg.REG_QWORD) {
printf("\t\t0x%llx (%lld)\n", v.value, v.value);
}
}
}
function list_path(path) {
var count = 0;
var list = reg.enum_path(path);
if (list == undefined) {
println("Unable to list " + path);
return 0;
}
var i;
list_values(path);
count = count + list.length;
for (i=0;i<list.length;i++) {
var npath;
if (path) {
npath = path + "\\" + list[i];
} else {
npath = list[i];
}
println(npath);
count = count + list_path(npath);
}
return count;
}
var root;
if (options.ARGV.length > 1) {
root = options.ARGV[1];
} else {
root = '';
}
if (options.createkey) {
var ok = reg.create_key("HKLM\\SOFTWARE", options.createkey);
if (!ok) {
println("Failed to create key");
}
} else {
printf("Listing registry tree '%s'\n", root);
var count = list_path(root);
if (count == 0) {
println("No entries found");
return 1;
}
}
return 0;
+95
View File
@@ -0,0 +1,95 @@
#######################
# Start LIBRARY EJSRPC
[SUBSYSTEM::EJSRPC]
OBJ_FILES = \
ejsrpc.o
# End SUBSYSTEM EJSRPC
#######################
[MODULE::smbcalls_config]
OBJ_FILES = smbcalls_config.o
SUBSYSTEM = smbcalls
INIT_FUNCTION = smb_setup_ejs_config
[MODULE::smbcalls_ldb]
OBJ_FILES = smbcalls_ldb.o
SUBSYSTEM = smbcalls
INIT_FUNCTION = smb_setup_ejs_ldb
[MODULE::smbcalls_nbt]
OBJ_FILES = smbcalls_nbt.o
SUBSYSTEM = smbcalls
INIT_FUNCTION = smb_setup_ejs_nbt
[MODULE::smbcalls_samba3]
OBJ_FILES = smbcalls_samba3.o
SUBSYSTEM = smbcalls
INIT_FUNCTION = smb_setup_ejs_samba3
PUBLIC_DEPENDENCIES = LIBSAMBA3
[MODULE::smbcalls_rand]
OBJ_FILES = smbcalls_rand.o
SUBSYSTEM = smbcalls
INIT_FUNCTION = smb_setup_ejs_random
[MODULE::smbcalls_nss]
OBJ_FILES = smbcalls_nss.o
SUBSYSTEM = smbcalls
INIT_FUNCTION = smb_setup_ejs_nss
[MODULE::smbcalls_data]
OBJ_FILES = smbcalls_data.o
SUBSYSTEM = smbcalls
INIT_FUNCTION = smb_setup_ejs_datablob
[MODULE::smbcalls_auth]
OBJ_FILES = smbcalls_auth.o
SUBSYSTEM = smbcalls
INIT_FUNCTION = smb_setup_ejs_auth
PUBLIC_DEPENDENCIES = auth
[MODULE::smbcalls_string]
OBJ_FILES = smbcalls_string.o
SUBSYSTEM = smbcalls
INIT_FUNCTION = smb_setup_ejs_string
[MODULE::smbcalls_sys]
OBJ_FILES = smbcalls_sys.o
SUBSYSTEM = smbcalls
INIT_FUNCTION = smb_setup_ejs_system
#######################
# Start LIBRARY smbcalls
[LIBRARY::smbcalls]
SO_VERSION = 0
VERSION = 0.0.1
PRIVATE_PROTO_HEADER = proto.h
OBJ_FILES = \
smbcalls.o \
smbcalls_cli.o \
smbcalls_rpc.o \
smbcalls_options.o \
smbcalls_creds.o \
smbcalls_param.o \
ejsnet.o \
mprutil.o \
literal.o
PUBLIC_DEPENDENCIES = \
EJS LIBSAMBA-UTIL \
EJSRPC MESSAGING \
LIBSAMBA-NET LIBCLI_SMB LIBPOPT \
CREDENTIALS POPT_CREDENTIALS POPT_SAMBA \
dcerpc \
NDR_TABLE
# End SUBSYSTEM smbcalls
#######################
#######################
# Start BINARY SMBSCRIPT
[BINARY::smbscript]
INSTALLDIR = BINDIR
OBJ_FILES = \
smbscript.o
PRIVATE_DEPENDENCIES = EJS LIBSAMBA-UTIL smbcalls LIBSAMBA-CONFIG
# End BINARY SMBSCRIPT
#######################
+377
View File
@@ -0,0 +1,377 @@
/*
Unix SMB/CIFS implementation.
provide interfaces to libnet calls from ejs scripts
Copyright (C) Rafal Szczesniak 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "lib/appweb/ejs/ejs.h"
#include "scripting/ejs/smbcalls.h"
#include "scripting/ejs/ejsnet.h"
#include "libnet/libnet.h"
#include "events/events.h"
#include "auth/credentials/credentials.h"
static int ejs_net_userman(MprVarHandle eid, int argc, struct MprVar** argv);
static int ejs_net_createuser(MprVarHandle eid, int argc, char **argv);
static int ejs_net_deleteuser(MprVarHandle eid, int argc, char **argv);
static int ejs_net_userinfo(MprVarHandle eid, int argc, char **argv);
static int ejs_net_join_domain(MprVarHandle eid, int argc, struct MprVar **argv);
static int ejs_net_samsync_ldb(MprVarHandle eid, int argc, struct MprVar **argv);
/*
Usage:
net = NetContext(credentials);
*/
static int ejs_net_context(MprVarHandle eid, int argc, struct MprVar **argv)
{
TALLOC_CTX *event_mem_ctx = talloc_new(mprMemCtx());
struct cli_credentials *creds;
struct libnet_context *ctx;
struct MprVar obj;
struct event_context *ev;
if (!event_mem_ctx) {
ejsSetErrorMsg(eid, "talloc_new() failed");
return -1;
}
ev = event_context_find(event_mem_ctx);
ctx = libnet_context_init(ev);
/* IF we generated a new event context, it will be under here,
* and we need it to last as long as the libnet context, so
* make it a child */
talloc_steal(ctx, event_mem_ctx);
if (argc == 0 || (argc == 1 && argv[0]->type == MPR_TYPE_NULL)) {
creds = cli_credentials_init(ctx);
if (creds == NULL) {
ejsSetErrorMsg(eid, "cli_credential_init() failed");
talloc_free(ctx);
return -1;
}
cli_credentials_set_conf(creds);
cli_credentials_set_anonymous(creds);
} else if (argc == 1 && argv[0]->type == MPR_TYPE_OBJECT) {
/* get credential values from credentials object */
creds = mprGetPtr(argv[0], "creds");
if (creds == NULL) {
ejsSetErrorMsg(eid, "userAuth requires a 'creds' first parameter");
talloc_free(ctx);
return -1;
}
} else {
ejsSetErrorMsg(eid, "NetContext invalid arguments, this function requires an object.");
talloc_free(ctx);
return -1;
}
ctx->cred = creds;
obj = mprObject("NetCtx");
mprSetPtrChild(&obj, "ctx", ctx);
mprSetCFunction(&obj, "UserMgr", ejs_net_userman);
mprSetCFunction(&obj, "JoinDomain", ejs_net_join_domain);
mprSetCFunction(&obj, "SamSyncLdb", ejs_net_samsync_ldb);
mpr_Return(eid, obj);
return 0;
}
static int ejs_net_join_domain(MprVarHandle eid, int argc, struct MprVar **argv)
{
TALLOC_CTX *mem_ctx;
struct libnet_context *ctx;
struct libnet_Join *join;
NTSTATUS status;
ctx = mprGetThisPtr(eid, "ctx");
mem_ctx = talloc_new(mprMemCtx());
join = talloc(mem_ctx, struct libnet_Join);
if (!join) {
talloc_free(mem_ctx);
return -1;
}
/* prepare parameters for the join */
join->in.netbios_name = NULL;
join->in.join_type = SEC_CHAN_WKSTA;
join->in.domain_name = cli_credentials_get_domain(ctx->cred);
join->in.level = LIBNET_JOIN_AUTOMATIC;
join->out.error_string = NULL;
if (argc == 1 && argv[0]->type == MPR_TYPE_OBJECT) {
MprVar *netbios_name = mprGetProperty(argv[0], "netbios_name", NULL);
MprVar *domain_name = mprGetProperty(argv[0], "domain_name", NULL);
MprVar *join_type = mprGetProperty(argv[0], "join_type", NULL);
if (netbios_name) {
join->in.netbios_name = mprToString(netbios_name);
}
if (domain_name) {
join->in.domain_name = mprToString(domain_name);
}
if (join_type) {
join->in.join_type = mprToInt(join_type);
}
}
if (!join->in.domain_name) {
ejsSetErrorMsg(eid, "a domain must be specified for to join");
talloc_free(mem_ctx);
return -1;
}
/* do the domain join */
status = libnet_Join(ctx, join, join);
if (!NT_STATUS_IS_OK(status)) {
MprVar error_string = mprString(join->out.error_string);
mprSetPropertyValue(argv[0], "error_string", error_string);
mpr_Return(eid, mprCreateBoolVar(False));
} else {
mpr_Return(eid, mprCreateBoolVar(True));
}
talloc_free(mem_ctx);
return 0;
}
static int ejs_net_samsync_ldb(MprVarHandle eid, int argc, struct MprVar **argv)
{
TALLOC_CTX *mem_ctx;
struct libnet_context *ctx;
struct libnet_samsync_ldb *samsync;
NTSTATUS status;
ctx = mprGetThisPtr(eid, "ctx");
mem_ctx = talloc_new(mprMemCtx());
samsync = talloc(mem_ctx, struct libnet_samsync_ldb);
if (!samsync) {
talloc_free(mem_ctx);
return -1;
}
/* prepare parameters for the samsync */
samsync->in.machine_account = NULL;
samsync->in.session_info = NULL;
samsync->in.binding_string = NULL;
samsync->out.error_string = NULL;
if (argc == 1 && argv[0]->type == MPR_TYPE_OBJECT) {
MprVar *credentials = mprGetProperty(argv[0], "machine_account", NULL);
MprVar *session_info = mprGetProperty(argv[0], "session_info", NULL);
if (credentials) {
samsync->in.machine_account = talloc_get_type(mprGetPtr(credentials, "creds"), struct cli_credentials);
}
if (session_info) {
samsync->in.session_info = talloc_get_type(mprGetPtr(session_info, "session_info"), struct auth_session_info);
}
}
/* do the domain samsync */
status = libnet_samsync_ldb(ctx, samsync, samsync);
if (!NT_STATUS_IS_OK(status)) {
MprVar error_string = mprString(samsync->out.error_string);
mprSetPropertyValue(argv[0], "error_string", error_string);
mpr_Return(eid, mprCreateBoolVar(False));
} else {
mpr_Return(eid, mprCreateBoolVar(True));
}
talloc_free(mem_ctx);
return 0;
}
/*
Usage:
usrCtx = net.UserMgr(domain);
*/
static int ejs_net_userman(MprVarHandle eid, int argc, struct MprVar **argv)
{
TALLOC_CTX *mem_ctx;
struct libnet_context *ctx;
const char *userman_domain = NULL;
struct MprVar *obj = NULL;
ctx = mprGetThisPtr(eid, "ctx");
mem_ctx = talloc_new(mprMemCtx());
if (argc == 0) {
userman_domain = cli_credentials_get_domain(ctx->cred);
} else if (argc == 1 && mprVarIsString(argv[0]->type)) {
userman_domain = talloc_strdup(ctx, mprToString(argv[0]));
} else {
ejsSetErrorMsg(eid, "too many arguments");
goto done;
}
if (!userman_domain) {
ejsSetErrorMsg(eid, "a domain must be specified for user management");
goto done;
}
obj = mprInitObject(eid, "NetUsrCtx", argc, argv);
mprSetPtrChild(obj, "ctx", ctx);
mprSetPtrChild(obj, "domain", userman_domain);
mprSetStringCFunction(obj, "Create", ejs_net_createuser);
mprSetStringCFunction(obj, "Delete", ejs_net_deleteuser);
mprSetStringCFunction(obj, "Info", ejs_net_userinfo);
return 0;
done:
talloc_free(mem_ctx);
return -1;
}
static int ejs_net_createuser(MprVarHandle eid, int argc, char **argv)
{
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
TALLOC_CTX *mem_ctx;
struct libnet_context *ctx;
const char *userman_domain = NULL;
struct libnet_CreateUser req;
if (argc != 1) {
ejsSetErrorMsg(eid, "argument 1 must be a string");
return -1;
}
ctx = mprGetThisPtr(eid, "ctx");
if (!ctx) {
ejsSetErrorMsg(eid, "ctx property returns null pointer");
return -1;
}
userman_domain = mprGetThisPtr(eid, "domain");
if (!userman_domain) {
ejsSetErrorMsg(eid, "domain property returns null pointer");
return -1;
}
mem_ctx = talloc_new(mprMemCtx());
req.in.domain_name = userman_domain;
req.in.user_name = argv[0];
status = libnet_CreateUser(ctx, mem_ctx, &req);
if (!NT_STATUS_IS_OK(status)) {
ejsSetErrorMsg(eid, "%s", req.out.error_string);
}
talloc_free(mem_ctx);
mpr_Return(eid, mprNTSTATUS(status));
return 0;
}
static int ejs_net_deleteuser(MprVarHandle eid, int argc, char **argv)
{
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
TALLOC_CTX *mem_ctx;
struct libnet_context *ctx;
const char *userman_domain = NULL;
struct libnet_DeleteUser req;
if (argc != 1) {
ejsSetErrorMsg(eid, "argument 1 must be a string");
return -1;
}
ctx = mprGetThisPtr(eid, "ctx");
if (!ctx) {
ejsSetErrorMsg(eid, "ctx property returns null pointer");
return -1;
}
userman_domain = mprGetThisPtr(eid, "domain");
if (!userman_domain) {
ejsSetErrorMsg(eid, "domain property returns null pointer");
return -1;
}
mem_ctx = talloc_new(mprMemCtx());
req.in.domain_name = userman_domain;
req.in.user_name = argv[0];
status = libnet_DeleteUser(ctx, mem_ctx, &req);
if (!NT_STATUS_IS_OK(status)) {
ejsSetErrorMsg(eid, "%s", req.out.error_string);
}
talloc_free(mem_ctx);
mpr_Return(eid, mprNTSTATUS(status));
return 0;
}
static int ejs_net_userinfo(MprVarHandle eid, int argc, char **argv)
{
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
TALLOC_CTX *mem_ctx;
struct libnet_context *ctx;
const char *userman_domain = NULL;
struct libnet_UserInfo req;
if (argc != 1) {
ejsSetErrorMsg(eid, "argument 1 must be a string");
return -1;
}
ctx = mprGetThisPtr(eid, "ctx");
if (!ctx) {
ejsSetErrorMsg(eid, "ctx property returns null pointer");
return -1;
}
userman_domain = mprGetThisPtr(eid, "domain");
if (!userman_domain) {
ejsSetErrorMsg(eid, "domain property returns null pointer");
return -1;
}
mem_ctx = talloc_new(mprMemCtx());
req.in.domain_name = userman_domain;
req.in.user_name = argv[0];
status = libnet_UserInfo(ctx, mem_ctx, &req);
if (!NT_STATUS_IS_OK(status)) {
ejsSetErrorMsg(eid, "%s", req.out.error_string);
}
/* TODO: create user info object and pass received properties */
talloc_free(mem_ctx);
return 0;
}
void ejsnet_setup(void)
{
ejsDefineCFunction(-1, "NetContext", ejs_net_context, NULL, MPR_VAR_SCRIPT_HANDLE);
}
+26
View File
@@ -0,0 +1,26 @@
/*
Unix SMB/CIFS implementation.
provide interfaces to libnet calls from ejs scripts
Copyright (C) Rafal Szczesniak 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "lib/appweb/ejs/ejs.h"
void ejsnet_setup(void);
+405
View File
@@ -0,0 +1,405 @@
/*
Unix SMB/CIFS implementation.
provide interfaces to rpc calls from ejs scripts
Copyright (C) Andrew Tridgell 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "lib/appweb/ejs/ejs.h"
#include "scripting/ejs/smbcalls.h"
#include "librpc/gen_ndr/lsa.h"
#include "librpc/gen_ndr/winreg.h"
#include "scripting/ejs/ejsrpc.h"
#include "libcli/security/security.h"
/*
set the switch var to be used by the next union switch
*/
void ejs_set_switch(struct ejs_rpc *ejs, uint32_t switch_var)
{
ejs->switch_var = switch_var;
}
/*
panic in the ejs wrapper code
*/
NTSTATUS ejs_panic(struct ejs_rpc *ejs, const char *why)
{
ejsSetErrorMsg(ejs->eid, "rpc_call '%s' failed - %s", ejs->callname, why);
return NT_STATUS_INTERNAL_ERROR;
}
/*
start the ejs pull process for a structure
*/
NTSTATUS ejs_pull_struct_start(struct ejs_rpc *ejs, struct MprVar **v, const char *name)
{
return mprGetVar(v, name);
}
/*
start the ejs push process for a structure
*/
NTSTATUS ejs_push_struct_start(struct ejs_rpc *ejs, struct MprVar **v, const char *name)
{
NDR_CHECK(mprSetVar(*v, name, mprObject(name)));
return mprGetVar(v, name);
}
/*
pull a uint8 from a mpr variable to a C element
*/
NTSTATUS ejs_pull_uint8(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, uint8_t *r)
{
NDR_CHECK(mprGetVar(&v, name));
*r = mprVarToInteger(v);
return NT_STATUS_OK;
}
NTSTATUS ejs_push_uint8(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const uint8_t *r)
{
return mprSetVar(v, name, mprCreateIntegerVar(*r));
}
/*
pull a uint16 from a mpr variable to a C element
*/
NTSTATUS ejs_pull_uint16(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, uint16_t *r)
{
NDR_CHECK(mprGetVar(&v, name));
*r = mprVarToInteger(v);
return NT_STATUS_OK;
}
NTSTATUS ejs_push_uint16(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const uint16_t *r)
{
return mprSetVar(v, name, mprCreateIntegerVar(*r));
}
/*
pull a uint32 from a mpr variable to a C element
*/
NTSTATUS ejs_pull_uint32(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, uint32_t *r)
{
NDR_CHECK(mprGetVar(&v, name));
*r = mprVarToInteger(v);
return NT_STATUS_OK;
}
NTSTATUS ejs_push_uint32(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const uint32_t *r)
{
return mprSetVar(v, name, mprCreateIntegerVar(*r));
}
/*
pull a int32 from a mpr variable to a C element
*/
NTSTATUS ejs_pull_int32(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, int32_t *r)
{
NDR_CHECK(mprGetVar(&v, name));
*r = mprVarToInteger(v);
return NT_STATUS_OK;
}
NTSTATUS ejs_push_int32(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const int32_t *r)
{
return mprSetVar(v, name, mprCreateIntegerVar(*r));
}
/*
pull a uint32 from a mpr variable to a C element
*/
NTSTATUS ejs_pull_time_t(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, time_t *r)
{
NDR_CHECK(mprGetVar(&v, name));
*r = mprVarToInteger(v);
return NT_STATUS_OK;
}
NTSTATUS ejs_push_time_t(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const time_t *r)
{
return mprSetVar(v, name, mprCreateIntegerVar(*r));
}
NTSTATUS ejs_pull_hyper(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, uint64_t *r)
{
NDR_CHECK(mprGetVar(&v, name));
*r = mprVarToNumber(v);
return NT_STATUS_OK;
}
NTSTATUS ejs_push_hyper(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const uint64_t *r)
{
return mprSetVar(v, name, mprCreateNumberVar(*r));
}
NTSTATUS ejs_pull_dlong(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, int64_t *r)
{
return ejs_pull_hyper(ejs, v, name, (uint64_t *)r);
}
NTSTATUS ejs_push_dlong(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const int64_t *r)
{
return ejs_push_hyper(ejs, v, name, (const uint64_t *)r);
}
NTSTATUS ejs_pull_udlong(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, uint64_t *r)
{
return ejs_pull_hyper(ejs, v, name, r);
}
NTSTATUS ejs_push_udlong(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const uint64_t *r)
{
return ejs_push_hyper(ejs, v, name, r);
}
NTSTATUS ejs_pull_NTTIME(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, uint64_t *r)
{
return ejs_pull_hyper(ejs, v, name, r);
}
NTSTATUS ejs_push_NTTIME(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const uint64_t *r)
{
return ejs_push_hyper(ejs, v, name, r);
}
NTSTATUS ejs_push_WERROR(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const WERROR *r)
{
return ejs_push_string(ejs, v, name, win_errstr(*r));
}
NTSTATUS ejs_push_NTSTATUS(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const NTSTATUS *r)
{
return ejs_push_string(ejs, v, name, nt_errstr(*r));
}
/*
pull a enum from a mpr variable to a C element
a enum is just treating as an unsigned integer at this level
*/
NTSTATUS ejs_pull_enum(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, unsigned *r)
{
NDR_CHECK(mprGetVar(&v, name));
*r = mprVarToInteger(v);
return NT_STATUS_OK;
}
NTSTATUS ejs_push_enum(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const unsigned *r)
{
return mprSetVar(v, name, mprCreateIntegerVar(*r));
}
/*
pull a string
*/
NTSTATUS ejs_pull_string(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const char **s)
{
NDR_CHECK(mprGetVar(&v, name));
*s = mprToString(v);
return NT_STATUS_OK;
}
/*
push a string
*/
NTSTATUS ejs_push_string(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const char *s)
{
return mprSetVar(v, name, mprString(s));
}
NTSTATUS ejs_pull_dom_sid(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, struct dom_sid *r)
{
struct dom_sid *sid;
NDR_CHECK(mprGetVar(&v, name));
sid = dom_sid_parse_talloc(ejs, mprToString(v));
NT_STATUS_HAVE_NO_MEMORY(sid);
*r = *sid;
return NT_STATUS_OK;
}
NTSTATUS ejs_push_dom_sid(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const struct dom_sid *r)
{
char *sidstr = dom_sid_string(ejs, r);
NT_STATUS_HAVE_NO_MEMORY(sidstr);
return mprSetVar(v, name, mprString(sidstr));
}
NTSTATUS ejs_pull_GUID(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, struct GUID *r)
{
NDR_CHECK(mprGetVar(&v, name));
return GUID_from_string(mprToString(v), r);
}
NTSTATUS ejs_push_GUID(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const struct GUID *r)
{
char *guid = GUID_string(ejs, r);
NT_STATUS_HAVE_NO_MEMORY(guid);
return mprSetVar(v, name, mprString(guid));
}
NTSTATUS ejs_push_null(struct ejs_rpc *ejs, struct MprVar *v, const char *name)
{
return mprSetVar(v, name, mprCreatePtrVar(NULL));
}
BOOL ejs_pull_null(struct ejs_rpc *ejs, struct MprVar *v, const char *name)
{
NTSTATUS status = mprGetVar(&v, name);
if (!NT_STATUS_IS_OK(status)) {
return False;
}
if (v->type == MPR_TYPE_PTR && v->ptr == NULL) {
return True;
}
return False;
}
/*
pull a lsa_String
*/
NTSTATUS ejs_pull_lsa_String(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, struct lsa_String *r)
{
return ejs_pull_string(ejs, v, name, &r->string);
}
/*
push a lsa_String
*/
NTSTATUS ejs_push_lsa_String(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const struct lsa_String *r)
{
return ejs_push_string(ejs, v, name, r->string);
}
/*
pull a winreg_String
*/
NTSTATUS ejs_pull_winreg_String(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, struct winreg_String *r)
{
return ejs_pull_string(ejs, v, name, &r->name);
}
/*
push a winreg_String
*/
NTSTATUS ejs_push_winreg_String(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const struct winreg_String *r)
{
return ejs_push_string(ejs, v, name, r->name);
}
NTSTATUS ejs_pull_DATA_BLOB(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, DATA_BLOB *r)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
NTSTATUS ejs_push_DATA_BLOB(struct ejs_rpc *ejs,
struct MprVar *v, const char *name,
const DATA_BLOB *r)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
NTSTATUS ejs_pull_BOOL(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, BOOL *r)
{
NDR_CHECK(mprGetVar(&v, name));
*r = mprVarToBool(v);
return NT_STATUS_OK;
}
NTSTATUS ejs_push_BOOL(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const BOOL *r)
{
return mprSetVar(v, name, mprCreateBoolVar(*r));
}
/*
pull a uint8 array from a mpr variable to a C element - treating as a data blob
*/
NTSTATUS ejs_pull_array_uint8(struct ejs_rpc *ejs,
struct MprVar *v, const char *name,
uint8_t *r, uint32_t length)
{
NTSTATUS status;
DATA_BLOB *blob;
status = mprGetVar(&v, name);
NT_STATUS_NOT_OK_RETURN(status);
blob = mprToDataBlob(v);
if (blob == NULL) {
return NT_STATUS_OBJECT_NAME_INVALID;
}
if (blob->length != length) {
return NT_STATUS_INFO_LENGTH_MISMATCH;
}
memcpy(r, blob->data, length);
return NT_STATUS_OK;
}
NTSTATUS ejs_push_array_uint8(struct ejs_rpc *ejs,
struct MprVar *v, const char *name,
const uint8_t *r, uint32_t length)
{
DATA_BLOB blob;
blob.data = discard_const(r);
blob.length = length;
mprSetVar(v, name, mprDataBlob(blob));
return NT_STATUS_OK;
}
+161
View File
@@ -0,0 +1,161 @@
/*
Unix SMB/CIFS implementation.
ejs <-> rpc interface definitions
Copyright (C) Andrew Tridgell 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "librpc/gen_ndr/security.h"
#include "librpc/rpc/dcerpc.h"
struct ejs_rpc {
int eid;
const char *callname;
/* as ejs does only one pass, we can use a single var for switch
handling */
uint32_t switch_var;
};
typedef NTSTATUS (*ejs_pull_t)(struct ejs_rpc *, struct MprVar *, const char *, void *);
typedef NTSTATUS (*ejs_push_t)(struct ejs_rpc *, struct MprVar *, const char *, const void *);
typedef NTSTATUS (*ejs_pull_function_t)(struct ejs_rpc *, struct MprVar *, void *);
typedef NTSTATUS (*ejs_push_function_t)(struct ejs_rpc *, struct MprVar *, const void *);
NTSTATUS ejs_panic(struct ejs_rpc *ejs, const char *why);
void ejs_set_switch(struct ejs_rpc *ejs, uint32_t switch_var);
NTSTATUS smbcalls_register_ejs(const char *name, MprCFunction fn);
int ejs_rpc_call(int eid, int argc, struct MprVar **argv,
const struct dcerpc_interface_table *iface, int callnum,
ejs_pull_function_t ejs_pull, ejs_push_function_t ejs_push);
NTSTATUS ejs_pull_struct_start(struct ejs_rpc *ejs, struct MprVar **v, const char *name);
NTSTATUS ejs_push_struct_start(struct ejs_rpc *ejs, struct MprVar **v, const char *name);
NTSTATUS ejs_pull_uint8(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, uint8_t *r);
NTSTATUS ejs_push_uint8(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const uint8_t *r);
NTSTATUS ejs_pull_uint16(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, uint16_t *r);
NTSTATUS ejs_push_uint16(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const uint16_t *r);
NTSTATUS ejs_pull_uint32(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, uint32_t *r);
NTSTATUS ejs_push_int32(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const int32_t *r);
NTSTATUS ejs_pull_int32(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, int32_t *r);
NTSTATUS ejs_push_uint32(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const uint32_t *r);
NTSTATUS ejs_pull_hyper(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, uint64_t *r);
NTSTATUS ejs_push_hyper(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const uint64_t *r);
NTSTATUS ejs_pull_dlong(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, int64_t *r);
NTSTATUS ejs_push_dlong(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const int64_t *r);
NTSTATUS ejs_pull_udlong(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, uint64_t *r);
NTSTATUS ejs_push_udlong(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const uint64_t *r);
NTSTATUS ejs_pull_NTTIME(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, uint64_t *r);
NTSTATUS ejs_push_NTTIME(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const uint64_t *r);
NTSTATUS ejs_pull_time_t(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, time_t *r);
NTSTATUS ejs_push_time_t(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const time_t *r);
NTSTATUS ejs_pull_enum(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, unsigned *r);
NTSTATUS ejs_push_enum(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const unsigned *r);
NTSTATUS ejs_pull_string(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const char **s);
NTSTATUS ejs_push_string(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const char *s);
void ejs_set_constant_int(int eid, const char *name, int value);
void ejs_set_constant_string(int eid, const char *name, const char *value);
NTSTATUS ejs_pull_dom_sid(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, struct dom_sid *r);
NTSTATUS ejs_push_dom_sid(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const struct dom_sid *r);
NTSTATUS ejs_push_null(struct ejs_rpc *ejs, struct MprVar *v, const char *name);
BOOL ejs_pull_null(struct ejs_rpc *ejs, struct MprVar *v, const char *name);
NTSTATUS ejs_push_WERROR(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const WERROR *r);
NTSTATUS ejs_push_NTSTATUS(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const NTSTATUS *r);
NTSTATUS ejs_pull_DATA_BLOB(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, DATA_BLOB *r);
NTSTATUS ejs_push_DATA_BLOB(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const DATA_BLOB *r);
NTSTATUS ejs_pull_BOOL(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, BOOL *r);
NTSTATUS ejs_push_BOOL(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const BOOL *r);
NTSTATUS ejs_pull_array_uint8(struct ejs_rpc *ejs,
struct MprVar *v, const char *name,
uint8_t *r, uint32_t length);
NTSTATUS ejs_push_array_uint8(struct ejs_rpc *ejs,
struct MprVar *v, const char *name,
const uint8_t *r, uint32_t length);
NTSTATUS ejs_pull_GUID(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, struct GUID *r);
NTSTATUS ejs_push_GUID(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const struct GUID *r);
struct lsa_String;
NTSTATUS ejs_pull_lsa_String(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, struct lsa_String *r);
NTSTATUS ejs_push_lsa_String(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const struct lsa_String *r);
struct winreg_String;
NTSTATUS ejs_pull_winreg_String(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, struct winreg_String *r);
NTSTATUS ejs_push_winreg_String(struct ejs_rpc *ejs,
struct MprVar *v, const char *name, const struct winreg_String *r);
#define EJS_ALLOC(ejs, s) do { \
(s) = talloc_ptrtype(ejs, (s)); \
if (!(s)) return ejs_panic(ejs, "out of memory"); \
} while (0)
#define EJS_ALLOC_N(ejs, s, n) do { \
(s) = talloc_array_ptrtype(ejs, (s), n); \
if (!(s)) return ejs_panic(ejs, "out of memory"); \
} while (0)
/* some types are equivalent for ejs */
#define ejs_pull_dom_sid2 ejs_pull_dom_sid
#define ejs_push_dom_sid2 ejs_push_dom_sid
#define ejs_pull_dom_sid28 ejs_pull_dom_sid
#define ejs_push_dom_sid28 ejs_push_dom_sid
#define ejs_pull_NTTIME_hyper ejs_pull_NTTIME
#define ejs_push_NTTIME_hyper ejs_push_NTTIME
#define ejs_pull_NTTIME_1sec ejs_pull_NTTIME
#define ejs_push_NTTIME_1sec ejs_push_NTTIME
+813
View File
@@ -0,0 +1,813 @@
/*
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
* Michael Clark <michael@metaparadigm.com>
* Copyright (c) 2006 Derrell Lipman
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See COPYING for details.
*
* Derrell Lipman:
* This version is modified from the original. It has been modified to
* natively use EJS variables rather than the original C object interface, and
* to use the talloc() family of functions for memory allocation.
*/
#include "includes.h"
#include "scripting/ejs/smbcalls.h"
enum json_tokener_error {
json_tokener_success,
json_tokener_error_oom, /* out of memory */
json_tokener_error_parse_unexpected,
json_tokener_error_parse_null,
json_tokener_error_parse_date,
json_tokener_error_parse_boolean,
json_tokener_error_parse_number,
json_tokener_error_parse_array,
json_tokener_error_parse_object,
json_tokener_error_parse_string,
json_tokener_error_parse_comment,
json_tokener_error_parse_eof
};
enum json_tokener_state {
json_tokener_state_eatws,
json_tokener_state_start,
json_tokener_state_finish,
json_tokener_state_null,
json_tokener_state_date,
json_tokener_state_comment_start,
json_tokener_state_comment,
json_tokener_state_comment_eol,
json_tokener_state_comment_end,
json_tokener_state_string,
json_tokener_state_string_escape,
json_tokener_state_escape_unicode,
json_tokener_state_boolean,
json_tokener_state_number,
json_tokener_state_array,
json_tokener_state_datelist,
json_tokener_state_array_sep,
json_tokener_state_datelist_sep,
json_tokener_state_object,
json_tokener_state_object_field_start,
json_tokener_state_object_field,
json_tokener_state_object_field_end,
json_tokener_state_object_value,
json_tokener_state_object_sep
};
enum date_field {
date_field_year,
date_field_month,
date_field_day,
date_field_hour,
date_field_minute,
date_field_second,
date_field_millisecond
};
struct json_tokener
{
char *source;
int pos;
void *ctx;
void *pb;
};
static const char *json_number_chars = "0123456789.+-e";
static const char *json_hex_chars = "0123456789abcdef";
#define hexdigit(x) (((x) <= '9') ? (x) - '0' : ((x) & 7) + 9)
extern struct MprVar json_tokener_parse(char *s);
static struct MprVar json_tokener_do_parse(struct json_tokener *this,
enum json_tokener_error *err_p);
/*
* literal_to_var() parses a string into an ejs variable. The ejs
* variable is returned. Upon error, the javascript variable will be
* `undefined`. This was created for parsing JSON, but is generally useful
* for parsing the literal forms of objects and arrays, since ejs doesn't
* procide that functionality.
*/
int literal_to_var(int eid, int argc, char **argv)
{
struct json_tokener tok;
struct MprVar obj;
enum json_tokener_error err = json_tokener_success;
if (argc != 1) {
ejsSetErrorMsg(eid,
"literal_to_var() requires one parameter: "
"the string to be parsed.");
return -1;
}
tok.source = argv[0];
tok.pos = 0;
tok.ctx = talloc_new(mprMemCtx());
if (tok.ctx == NULL) {
mpr_Return(eid, mprCreateUndefinedVar());
return 0;
}
tok.pb = talloc_zero_size(tok.ctx, 1);
if (tok.pb == NULL) {
mpr_Return(eid, mprCreateUndefinedVar());
return 0;
}
obj = json_tokener_do_parse(&tok, &err);
talloc_free(tok.pb);
if (err != json_tokener_success) {
mprDestroyVar(&obj);
mpr_Return(eid, mprCreateUndefinedVar());
return 0;
}
mpr_Return(eid, obj);
return 0;
}
static void *append_string(void *ctx,
char *orig,
char *append,
int size)
{
char c;
char *end_p = append + size;
void *ret;
/*
* We need to null terminate the string to be copied. Save character at
* the size limit of the source string.
*/
c = *end_p;
/* Temporarily null-terminate it */
*end_p = '\0';
/* Append the requested data */
ret = talloc_append_string(ctx, orig, append);
/* Restore the original character in place of our temporary null byte */
*end_p = c;
/* Give 'em what they came for */
return ret;
}
static struct MprVar json_tokener_do_parse(struct json_tokener *this,
enum json_tokener_error *err_p)
{
enum json_tokener_state state;
enum json_tokener_state saved_state;
enum date_field date_field;
struct MprVar current = mprCreateUndefinedVar();
struct MprVar tempObj;
struct MprVar obj;
enum json_tokener_error err = json_tokener_success;
char date_script[] = "JSON_Date.create(0);";
char *obj_field_name = NULL;
char *emsg = NULL;
char quote_char;
int deemed_double;
int start_offset;
char c;
state = json_tokener_state_eatws;
saved_state = json_tokener_state_start;
do {
c = this->source[this->pos];
switch(state) {
case json_tokener_state_eatws:
if(isspace(c)) {
this->pos++;
} else if(c == '/') {
state = json_tokener_state_comment_start;
start_offset = this->pos++;
} else {
state = saved_state;
}
break;
case json_tokener_state_start:
switch(c) {
case '{':
state = json_tokener_state_eatws;
saved_state = json_tokener_state_object;
current = mprObject(NULL);
this->pos++;
break;
case '[':
state = json_tokener_state_eatws;
saved_state = json_tokener_state_array;
current = mprArray(NULL);
this->pos++;
break;
case 'N':
case 'n':
start_offset = this->pos++;
if (this->source[this->pos] == 'e') {
state = json_tokener_state_date;
} else {
state = json_tokener_state_null;
}
break;
case '"':
case '\'':
quote_char = c;
talloc_free(this->pb);
this->pb = talloc_zero_size(this->ctx, 1);
if (this->pb == NULL) {
*err_p = json_tokener_error_oom;
goto out;
}
state = json_tokener_state_string;
start_offset = ++this->pos;
break;
case 'T':
case 't':
case 'F':
case 'f':
state = json_tokener_state_boolean;
start_offset = this->pos++;
break;
#if defined(__GNUC__)
case '0' ... '9':
#else
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
#endif
case '-':
deemed_double = 0;
state = json_tokener_state_number;
start_offset = this->pos++;
break;
default:
err = json_tokener_error_parse_unexpected;
goto out;
}
break;
case json_tokener_state_finish:
goto out;
case json_tokener_state_null:
if(strncasecmp("null",
this->source + start_offset,
this->pos - start_offset)) {
*err_p = json_tokener_error_parse_null;
mprDestroyVar(&current);
return mprCreateUndefinedVar();
}
if(this->pos - start_offset == 4) {
mprDestroyVar(&current);
current = mprCreateNullVar();
saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws;
} else {
this->pos++;
}
break;
case json_tokener_state_date:
if (this->pos - start_offset <= 18) {
if (strncasecmp("new Date(Date.UTC(",
this->source + start_offset,
this->pos - start_offset)) {
*err_p = json_tokener_error_parse_date;
mprDestroyVar(&current);
return mprCreateUndefinedVar();
} else {
this->pos++;
break;
}
}
this->pos--; /* we went one too far */
state = json_tokener_state_eatws;
saved_state = json_tokener_state_datelist;
/* Create a JsonDate object */
if (ejsEvalScript(0,
date_script,
&tempObj,
&emsg) != 0) {
*err_p = json_tokener_error_parse_date;
mprDestroyVar(&current);
return mprCreateUndefinedVar();
}
mprDestroyVar(&current);
mprCopyVar(&current, &tempObj, MPR_DEEP_COPY);
date_field = date_field_year;
break;
case json_tokener_state_comment_start:
if(c == '*') {
state = json_tokener_state_comment;
} else if(c == '/') {
state = json_tokener_state_comment_eol;
} else {
err = json_tokener_error_parse_comment;
goto out;
}
this->pos++;
break;
case json_tokener_state_comment:
if(c == '*') state = json_tokener_state_comment_end;
this->pos++;
break;
case json_tokener_state_comment_eol:
if(c == '\n') {
state = json_tokener_state_eatws;
}
this->pos++;
break;
case json_tokener_state_comment_end:
if(c == '/') {
state = json_tokener_state_eatws;
} else {
state = json_tokener_state_comment;
}
this->pos++;
break;
case json_tokener_state_string:
if(c == quote_char) {
this->pb = append_string(
this->ctx,
this->pb,
this->source + start_offset,
this->pos - start_offset);
if (this->pb == NULL) {
err = json_tokener_error_oom;
goto out;
}
current = mprString(this->pb);
saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws;
} else if(c == '\\') {
saved_state = json_tokener_state_string;
state = json_tokener_state_string_escape;
}
this->pos++;
break;
case json_tokener_state_string_escape:
switch(c) {
case '"':
case '\\':
this->pb = append_string(
this->ctx,
this->pb,
this->source + start_offset,
this->pos - start_offset - 1);
if (this->pb == NULL) {
err = json_tokener_error_oom;
goto out;
}
start_offset = this->pos++;
state = saved_state;
break;
case 'b':
case 'n':
case 'r':
case 't':
this->pb = append_string(
this->ctx,
this->pb,
this->source + start_offset,
this->pos - start_offset - 1);
if (this->pb == NULL) {
err = json_tokener_error_oom;
goto out;
}
if (c == 'b') {
/*
* second param to append_string()
* gets temporarily modified; can't
* pass string constant.
*/
char buf[] = "\b";
this->pb = append_string(this->ctx,
this->pb,
buf,
1);
if (this->pb == NULL) {
err = json_tokener_error_oom;
goto out;
}
} else if (c == 'n') {
char buf[] = "\n";
this->pb = append_string(this->ctx,
this->pb,
buf,
1);
if (this->pb == NULL) {
err = json_tokener_error_oom;
goto out;
}
} else if (c == 'r') {
char buf[] = "\r";
this->pb = append_string(this->ctx,
this->pb,
buf,
1);
if (this->pb == NULL) {
err = json_tokener_error_oom;
goto out;
}
} else if (c == 't') {
char buf[] = "\t";
this->pb = append_string(this->ctx,
this->pb,
buf,
1);
if (this->pb == NULL) {
err = json_tokener_error_oom;
goto out;
}
}
start_offset = ++this->pos;
state = saved_state;
break;
case 'u':
this->pb = append_string(
this->ctx,
this->pb,
this->source + start_offset,
this->pos - start_offset - 1);
if (this->pb == NULL) {
err = json_tokener_error_oom;
goto out;
}
start_offset = ++this->pos;
state = json_tokener_state_escape_unicode;
break;
default:
err = json_tokener_error_parse_string;
goto out;
}
break;
case json_tokener_state_escape_unicode:
if(strchr(json_hex_chars, c)) {
this->pos++;
if(this->pos - start_offset == 4) {
unsigned char utf_out[3];
unsigned int ucs_char =
(hexdigit(*(this->source + start_offset)) << 12) +
(hexdigit(*(this->source + start_offset + 1)) << 8) +
(hexdigit(*(this->source + start_offset + 2)) << 4) +
hexdigit(*(this->source + start_offset + 3));
if (ucs_char < 0x80) {
utf_out[0] = ucs_char;
this->pb = append_string(
this->ctx,
this->pb,
(char *) utf_out,
1);
if (this->pb == NULL) {
err = json_tokener_error_oom;
goto out;
}
} else if (ucs_char < 0x800) {
utf_out[0] = 0xc0 | (ucs_char >> 6);
utf_out[1] = 0x80 | (ucs_char & 0x3f);
this->pb = append_string(
this->ctx,
this->pb,
(char *) utf_out,
2);
if (this->pb == NULL) {
err = json_tokener_error_oom;
goto out;
}
} else {
utf_out[0] = 0xe0 | (ucs_char >> 12);
utf_out[1] = 0x80 | ((ucs_char >> 6) & 0x3f);
utf_out[2] = 0x80 | (ucs_char & 0x3f);
this->pb = append_string(
this->ctx,
this->pb,
(char *) utf_out,
3);
if (this->pb == NULL) {
err = json_tokener_error_oom;
goto out;
}
}
start_offset = this->pos;
state = saved_state;
}
} else {
err = json_tokener_error_parse_string;
goto out;
}
break;
case json_tokener_state_boolean:
if(strncasecmp("true", this->source + start_offset,
this->pos - start_offset) == 0) {
if(this->pos - start_offset == 4) {
current = mprCreateBoolVar(1);
saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws;
} else {
this->pos++;
}
} else if(strncasecmp("false", this->source + start_offset,
this->pos - start_offset) == 0) {
if(this->pos - start_offset == 5) {
current = mprCreateBoolVar(0);
saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws;
} else {
this->pos++;
}
} else {
err = json_tokener_error_parse_boolean;
goto out;
}
break;
case json_tokener_state_number:
if(!c || !strchr(json_number_chars, c)) {
int numi;
double numd;
char *tmp = talloc_strndup(
this->ctx,
this->source + start_offset,
this->pos - start_offset);
if (tmp == NULL) {
err = json_tokener_error_oom;
goto out;
}
if(!deemed_double && sscanf(tmp, "%d", &numi) == 1) {
current = mprCreateIntegerVar(numi);
} else if(deemed_double && sscanf(tmp, "%lf", &numd) == 1) {
current = mprCreateFloatVar(numd);
} else {
talloc_free(tmp);
err = json_tokener_error_parse_number;
goto out;
}
talloc_free(tmp);
saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws;
} else {
if(c == '.' || c == 'e') deemed_double = 1;
this->pos++;
}
break;
case json_tokener_state_array:
if(c == ']') {
this->pos++;
saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws;
} else {
int oldlen;
char idx[16];
obj = json_tokener_do_parse(this, &err);
if (err != json_tokener_success) {
goto out;
}
oldlen = mprToInt(mprGetProperty(&current,
"length",
NULL));
mprItoa(oldlen, idx, sizeof(idx));
mprSetVar(&current, idx, obj);
saved_state = json_tokener_state_array_sep;
state = json_tokener_state_eatws;
}
break;
case json_tokener_state_datelist:
if(c == ')') {
if (this->source[this->pos+1] == ')') {
this->pos += 2;
saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws;
} else {
err = json_tokener_error_parse_date;
goto out;
}
} else {
obj = json_tokener_do_parse(this, &err);
if (err != json_tokener_success) {
goto out;
}
/* date list items must be integers */
if (obj.type != MPR_TYPE_INT) {
err = json_tokener_error_parse_date;
goto out;
}
switch(date_field) {
case date_field_year:
mprSetVar(&current, "year", obj);
break;
case date_field_month:
mprSetVar(&current, "month", obj);
break;
case date_field_day:
mprSetVar(&current, "day", obj);
break;
case date_field_hour:
mprSetVar(&current, "hour", obj);
break;
case date_field_minute:
mprSetVar(&current, "minute", obj);
break;
case date_field_second:
mprSetVar(&current, "second", obj);
break;
case date_field_millisecond:
mprSetVar(&current, "millisecond", obj);
break;
default:
err = json_tokener_error_parse_date;
goto out;
}
/* advance to the next date field */
date_field++;
saved_state = json_tokener_state_datelist_sep;
state = json_tokener_state_eatws;
}
break;
case json_tokener_state_array_sep:
if(c == ']') {
this->pos++;
saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws;
} else if(c == ',') {
this->pos++;
saved_state = json_tokener_state_array;
state = json_tokener_state_eatws;
} else {
*err_p = json_tokener_error_parse_array;
mprDestroyVar(&current);
return mprCreateUndefinedVar();
}
break;
case json_tokener_state_datelist_sep:
if(c == ')') {
if (this->source[this->pos+1] == ')') {
this->pos += 2;
saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws;
} else {
err = json_tokener_error_parse_date;
goto out;
}
} else if(c == ',') {
this->pos++;
saved_state = json_tokener_state_datelist;
state = json_tokener_state_eatws;
} else {
*err_p = json_tokener_error_parse_date;
mprDestroyVar(&current);
return mprCreateUndefinedVar();
}
break;
case json_tokener_state_object:
state = json_tokener_state_object_field_start;
start_offset = this->pos;
break;
case json_tokener_state_object_field_start:
if(c == '}') {
this->pos++;
saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws;
} else if (c == '"' || c == '\'') {
quote_char = c;
talloc_free(this->pb);
this->pb = talloc_zero_size(this->ctx, 1);
if (this->pb == NULL) {
*err_p = json_tokener_error_oom;
goto out;
}
state = json_tokener_state_object_field;
start_offset = ++this->pos;
} else {
err = json_tokener_error_parse_object;
goto out;
}
break;
case json_tokener_state_object_field:
if(c == quote_char) {
this->pb = append_string(
this->ctx,
this->pb,
this->source + start_offset,
this->pos - start_offset);
if (this->pb == NULL) {
err = json_tokener_error_oom;
goto out;
}
obj_field_name = talloc_strdup(this->ctx,
this->pb);
if (obj_field_name == NULL) {
err = json_tokener_error_oom;
goto out;
}
saved_state = json_tokener_state_object_field_end;
state = json_tokener_state_eatws;
} else if(c == '\\') {
saved_state = json_tokener_state_object_field;
state = json_tokener_state_string_escape;
}
this->pos++;
break;
case json_tokener_state_object_field_end:
if(c == ':') {
this->pos++;
saved_state = json_tokener_state_object_value;
state = json_tokener_state_eatws;
} else {
*err_p = json_tokener_error_parse_object;
mprDestroyVar(&current);
return mprCreateUndefinedVar();
}
break;
case json_tokener_state_object_value:
obj = json_tokener_do_parse(this, &err);
if (err != json_tokener_success) {
goto out;
}
mprSetVar(&current, obj_field_name, obj);
talloc_free(obj_field_name);
obj_field_name = NULL;
saved_state = json_tokener_state_object_sep;
state = json_tokener_state_eatws;
break;
case json_tokener_state_object_sep:
if(c == '}') {
this->pos++;
saved_state = json_tokener_state_finish;
state = json_tokener_state_eatws;
} else if(c == ',') {
this->pos++;
saved_state = json_tokener_state_object;
state = json_tokener_state_eatws;
} else {
err = json_tokener_error_parse_object;
goto out;
}
break;
}
} while(c);
if(state != json_tokener_state_finish &&
saved_state != json_tokener_state_finish)
err = json_tokener_error_parse_eof;
out:
talloc_free(obj_field_name);
if(err == json_tokener_success) {
return current;
} else {
mprDestroyVar(&current);
*err_p = err;
return mprCreateUndefinedVar();
}
}
void smb_setup_ejs_literal(void)
{
ejsDefineStringCFunction(-1,
"literal_to_var",
literal_to_var,
NULL,
MPR_VAR_SCRIPT_HANDLE);
}
+482
View File
@@ -0,0 +1,482 @@
/*
Unix SMB/CIFS implementation.
utility functions for manipulating mpr variables in ejs calls
Copyright (C) Andrew Tridgell 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "lib/appweb/ejs/ejs.h"
#include "lib/ldb/include/ldb.h"
#include "scripting/ejs/smbcalls.h"
/*
return a default mpr object
*/
struct MprVar mprObject(const char *name)
{
return ejsCreateObj(name && *name?name:"(NULL)", MPR_DEFAULT_HASH_SIZE);
}
/*
return a empty mpr array
*/
struct MprVar mprArray(const char *name)
{
return ejsCreateArray(name && *name?name:"(NULL)", 0);
}
/*
find a mpr component, allowing for sub objects, using the '.' convention
*/
NTSTATUS mprGetVar(struct MprVar **v, const char *name)
{
const char *p = strchr(name, '.');
char *objname;
NTSTATUS status;
if (p == NULL) {
*v = mprGetProperty(*v, name, NULL);
if (*v == NULL) {
DEBUG(1,("mprGetVar unable to find '%s'\n", name));
return NT_STATUS_INVALID_PARAMETER;
}
return NT_STATUS_OK;
}
objname = talloc_strndup(mprMemCtx(), name, p-name);
NT_STATUS_HAVE_NO_MEMORY(objname);
*v = mprGetProperty(*v, objname, NULL);
NT_STATUS_HAVE_NO_MEMORY(*v);
status = mprGetVar(v, p+1);
talloc_free(objname);
return status;
}
/*
set a mpr component, allowing for sub objects, using the '.' convention
destroys 'val' after setting
*/
NTSTATUS mprSetVar(struct MprVar *v, const char *name, struct MprVar val)
{
const char *p = strchr(name, '.');
char *objname;
struct MprVar *v2;
NTSTATUS status;
if (p == NULL) {
v2 = mprSetProperty(v, name, &val);
if (v2 == NULL) {
DEBUG(1,("mprSetVar unable to set '%s'\n", name));
return NT_STATUS_INVALID_PARAMETER_MIX;
}
mprDestroyVar(&val);
return NT_STATUS_OK;
}
objname = talloc_strndup(mprMemCtx(), name, p-name);
if (objname == NULL) {
return NT_STATUS_NO_MEMORY;
}
v2 = mprGetProperty(v, objname, NULL);
if (v2 == NULL) {
mprSetVar(v, objname, mprObject(objname));
v2 = mprGetProperty(v, objname, NULL);
}
status = mprSetVar(v2, p+1, val);
talloc_free(objname);
return status;
}
/*
add an indexed array element to a property
*/
void mprAddArray(struct MprVar *var, int i, struct MprVar v)
{
char idx[16];
mprItoa(i, idx, sizeof(idx));
mprSetVar(var, idx, v);
}
/*
construct a MprVar from a list
*/
struct MprVar mprList(const char *name, const char **list)
{
struct MprVar var;
int i;
var = mprArray(name);
for (i=0;list && list[i];i++) {
mprAddArray(&var, i, mprString(list[i]));
}
return var;
}
/*
construct a MprVar from a string, using NULL if needed
*/
struct MprVar mprString(const char *s)
{
if (s == NULL) {
return mprCreatePtrVar(NULL);
}
return mprCreateStringVar(s, True);
}
/*
construct a string MprVar from a lump of data
*/
struct MprVar mprData(const uint8_t *p, size_t length)
{
struct MprVar var;
char *s = talloc_strndup(mprMemCtx(), (const char *)p, length);
if (s == NULL) {
return mprCreateUndefinedVar();
}
var = mprString(s);
talloc_free(s);
return var;
}
/*
turn a ldb_message into a ejs object variable
*/
static struct MprVar mprLdbMessage(struct ldb_context *ldb, struct ldb_message *msg)
{
struct MprVar var;
int i;
/* we force some attributes to always be an array in the
returned structure. This makes the scripting easier, as you don't
need a special case for the single value case */
const char *multivalued[] = { "objectClass", "memberOf", "privilege",
"member", NULL };
var = mprObject(ldb_dn_alloc_linearized(msg, msg->dn));
for (i=0;i<msg->num_elements;i++) {
struct ldb_message_element *el = &msg->elements[i];
struct MprVar val;
const struct ldb_attrib_handler *attr;
struct ldb_val v;
attr = ldb_attrib_handler(ldb, el->name);
if (attr == NULL) {
goto failed;
}
if (el->num_values == 1 &&
!str_list_check_ci(multivalued, el->name)) {
if (attr->ldif_write_fn(ldb, msg, &el->values[0], &v) != 0) {
goto failed;
}
/* FIXME: nasty hack, remove me when ejs will support
* arbitrary string and does not truncate on \0 */
if (strlen((char *)v.data) != v.length) {
val = mprDataBlob(v);
} else {
val = mprData(v.data, v.length);
}
} else {
int j;
val = mprArray(el->name);
for (j=0;j<el->num_values;j++) {
if (attr->ldif_write_fn(ldb, msg,
&el->values[j], &v) != 0) {
goto failed;
}
/* FIXME: nasty hack, remove me when ejs will support
* arbitrary string and does not truncate on \0 */
if (strlen((char *)v.data) != v.length) {
mprAddArray(&val, j, mprDataBlob(v));
} else {
mprAddArray(&val, j, mprData(v.data, v.length));
}
}
}
mprSetVar(&var, el->name, val);
}
/* add the dn if it is not already specified */
if (mprGetProperty(&var, "dn", 0) == 0) {
mprSetVar(&var, "dn", mprString(ldb_dn_alloc_linearized(msg, msg->dn)));
}
return var;
failed:
return mprCreateUndefinedVar();
}
/*
turn an array of ldb_messages into a ejs object variable
*/
struct MprVar mprLdbArray(struct ldb_context *ldb,
struct ldb_message **msg, int count, const char *name)
{
struct MprVar res;
int i;
res = mprArray(name);
for (i=0;i<count;i++) {
mprAddArray(&res, i, mprLdbMessage(ldb, msg[i]));
}
return res;
}
/*
turn a MprVar string variable into a const char *
*/
const char *mprToString(struct MprVar *v)
{
if (v->trigger) {
mprReadProperty(v, 0);
}
if (!mprVarIsString(v->type)) return NULL;
return v->string;
}
/*
turn a MprVar integer variable into an int
*/
int mprToInt(struct MprVar *v)
{
if (v->trigger) {
mprReadProperty(v, 0);
}
if (!mprVarIsNumber(v->type)) return 0;
return mprVarToNumber(v);
}
/*
turn a MprVar object variable into a string list
this assumes the object variable consists only of strings
*/
const char **mprToList(TALLOC_CTX *mem_ctx, struct MprVar *v)
{
const char **list = NULL;
struct MprVar *el;
if (v->type != MPR_TYPE_OBJECT ||
v->properties == NULL) {
return NULL;
}
for (el=mprGetFirstProperty(v, MPR_ENUM_DATA);
el;
el=mprGetNextProperty(v, el, MPR_ENUM_DATA)) {
const char *s = mprToString(el);
if (s) {
list = str_list_add(list, s);
}
}
talloc_steal(mem_ctx, list);
return list;
}
/*
turn a MprVar object variable into a string list
this assumes the object variable is an array of strings
*/
const char **mprToArray(TALLOC_CTX *mem_ctx, struct MprVar *v)
{
const char **list = NULL;
struct MprVar *len;
int length, i;
len = mprGetProperty(v, "length", NULL);
if (len == NULL) {
return NULL;
}
length = mprToInt(len);
for (i=0;i<length;i++) {
char idx[16];
struct MprVar *vs;
mprItoa(i, idx, sizeof(idx));
vs = mprGetProperty(v, idx, NULL);
if (vs == NULL || vs->type != MPR_TYPE_STRING) {
talloc_free(list);
return NULL;
}
list = str_list_add(list, mprToString(vs));
}
talloc_steal(mem_ctx, list);
return list;
}
/*
turn a NTSTATUS into a MprVar object with lots of funky properties
*/
struct MprVar mprNTSTATUS(NTSTATUS status)
{
struct MprVar res;
res = mprObject("ntstatus");
mprSetVar(&res, "errstr", mprString(nt_errstr(status)));
mprSetVar(&res, "v", mprCreateIntegerVar(NT_STATUS_V(status)));
mprSetVar(&res, "is_ok", mprCreateBoolVar(NT_STATUS_IS_OK(status)));
mprSetVar(&res, "is_err", mprCreateBoolVar(NT_STATUS_IS_ERR(status)));
return res;
}
/*
create a data-blob in a mpr variable
*/
struct MprVar mprDataBlob(DATA_BLOB blob)
{
struct MprVar res;
struct datablob *pblob = talloc(mprMemCtx(), struct datablob);
*pblob = data_blob_talloc(pblob, blob.data, blob.length);
res = mprObject("DATA_BLOB");
mprSetVar(&res, "size", mprCreateIntegerVar(blob.length));
mprSetPtrChild(&res, "blob", pblob);
return res;
}
/*
return a data blob from a mpr var created using mprDataBlob
*/
struct datablob *mprToDataBlob(struct MprVar *v)
{
return talloc_get_type(mprGetPtr(v, "blob"), struct datablob);
}
/*
turn a WERROR into a MprVar object with lots of funky properties
*/
struct MprVar mprWERROR(WERROR status)
{
struct MprVar res;
res = mprObject("werror");
mprSetVar(&res, "errstr", mprString(win_errstr(status)));
mprSetVar(&res, "v", mprCreateIntegerVar(W_ERROR_V(status)));
mprSetVar(&res, "is_ok", mprCreateBoolVar(W_ERROR_IS_OK(status)));
mprSetVar(&res, "is_err", mprCreateBoolVar(!W_ERROR_IS_OK(status)));
return res;
}
/*
set a pointer in a existing MprVar
*/
void mprSetPtr(struct MprVar *v, const char *propname, const void *p)
{
mprSetVar(v, propname, mprCreatePtrVar(discard_const(p)));
}
/*
set a pointer in a existing MprVar, freeing it when the property goes away
*/
void mprSetPtrChild(struct MprVar *v, const char *propname, const void *p)
{
mprSetVar(v, propname, mprCreatePtrVar(discard_const(p)));
v = mprGetProperty(v, propname, NULL);
v->allocatedData = 1;
talloc_steal(mprMemCtx(), p);
}
/*
get a pointer from a MprVar
*/
void *mprGetPtr(struct MprVar *v, const char *propname)
{
struct MprVar *val;
val = mprGetProperty(v, propname, NULL);
if (val == NULL) {
return NULL;
}
if (val->type != MPR_TYPE_PTR) {
return NULL;
}
return val->ptr;
}
/*
set the return value then free the variable
*/
void mpr_Return(int eid, struct MprVar v)
{
ejsSetReturnValue(eid, v);
mprDestroyVar(&v);
}
/*
set the return value then free the variable
*/
void mpr_ReturnString(int eid, const char *s)
{
mpr_Return(eid, mprString(s));
}
/*
set a C function in a variable
*/
void mprSetCFunction(struct MprVar *obj, const char *name, MprCFunction fn)
{
mprSetVar(obj, name, mprCreateCFunctionVar(fn, obj, MPR_VAR_SCRIPT_HANDLE));
}
/*
set a string C function in a variable
*/
void mprSetStringCFunction(struct MprVar *obj, const char *name, MprStringCFunction fn)
{
mprSetVar(obj, name, mprCreateStringCFunctionVar(fn, obj, MPR_VAR_SCRIPT_HANDLE));
}
/*
get a pointer in the current object
*/
void *mprGetThisPtr(int eid, const char *name)
{
struct MprVar *this = mprGetProperty(ejsGetLocalObject(eid), "this", 0);
return mprGetPtr(this, name);
}
/*
set a pointer as a child of the local object
*/
void mprSetThisPtr(int eid, const char *name, void *ptr)
{
struct MprVar *this = mprGetProperty(ejsGetLocalObject(eid), "this", 0);
mprSetPtrChild(this, name, ptr);
}
/*
used by object xxx_init() routines to allow for the caller
to supply a pre-existing object to add properties to,
or create a new object. This makes inheritance easy
*/
struct MprVar *mprInitObject(int eid, const char *name, int argc, struct MprVar **argv)
{
if (argc > 0 && mprVarIsObject(argv[0]->type)) {
return argv[0];
}
mpr_Return(eid, mprObject(name));
return ejsGetReturnValue(eid);
}
+247
View File
@@ -0,0 +1,247 @@
/*
Unix SMB/CIFS implementation.
provide hooks into smbd C calls from ejs scripts
Copyright (C) Andrew Tridgell 2005
Copyright (C) Tim Potter 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "lib/appweb/ejs/ejs.h"
#include "scripting/ejs/smbcalls.h"
#include "build.h"
#include "version.h"
/*
return the type of a variable
*/
static int ejs_typeof(MprVarHandle eid, int argc, struct MprVar **argv)
{
const struct {
MprType type;
const char *name;
} types[] = {
{ MPR_TYPE_UNDEFINED, "undefined" },
{ MPR_TYPE_NULL, "object" },
{ MPR_TYPE_BOOL, "boolean" },
{ MPR_TYPE_CFUNCTION, "function" },
{ MPR_TYPE_FLOAT, "number" },
{ MPR_TYPE_INT, "number" },
{ MPR_TYPE_INT64, "number" },
{ MPR_TYPE_OBJECT, "object" },
{ MPR_TYPE_FUNCTION, "function" },
{ MPR_TYPE_STRING, "string" },
{ MPR_TYPE_STRING_CFUNCTION, "function" },
{ MPR_TYPE_PTR, "pointer" }
};
int i;
const char *type = NULL;
if (argc != 1) return -1;
for (i=0;i<ARRAY_SIZE(types);i++) {
if (argv[0]->type == types[i].type) {
type = types[i].name;
break;
}
}
if (type == NULL) return -1;
mpr_ReturnString(eid, type);
return 0;
}
/*
return the native type of a variable
*/
static int ejs_typeof_native(MprVarHandle eid, int argc, struct MprVar **argv)
{
const struct {
MprType type;
const char *name;
} types[] = {
{ MPR_TYPE_UNDEFINED, "undefined" },
{ MPR_TYPE_NULL, "null" },
{ MPR_TYPE_BOOL, "boolean" },
{ MPR_TYPE_CFUNCTION, "c_function" },
{ MPR_TYPE_FLOAT, "float" },
{ MPR_TYPE_INT, "integer" },
{ MPR_TYPE_INT64, "integer64" },
{ MPR_TYPE_OBJECT, "object" },
{ MPR_TYPE_FUNCTION, "js_function" },
{ MPR_TYPE_STRING, "string" },
{ MPR_TYPE_STRING_CFUNCTION, "string_c_function" },
{ MPR_TYPE_PTR, "pointer" }
};
int i;
const char *type = NULL;
if (argc != 1) return -1;
for (i=0;i<ARRAY_SIZE(types);i++) {
if (argv[0]->type == types[i].type) {
type = types[i].name;
break;
}
}
if (type == NULL) return -1;
mpr_ReturnString(eid, type);
return 0;
}
/*
libinclude() allows you to include js files using a search path specified
in "js include =" in smb.conf.
*/
static int ejs_libinclude(int eid, int argc, char **argv)
{
int i, j;
const char **js_include = lp_js_include();
if (js_include == NULL || js_include[0] == NULL) {
ejsSetErrorMsg(eid, "js include path not set");
return -1;
}
for (i = 0; i < argc; i++) {
const char *script = argv[i];
for (j=0;js_include[j];j++) {
char *path;
path = talloc_asprintf(mprMemCtx(), "%s/%s", js_include[j], script);
if (path == NULL) {
return -1;
}
if (file_exist(path)) {
int ret;
struct MprVar result;
char *emsg;
ret = ejsEvalFile(eid, path, &result, &emsg);
talloc_free(path);
if (ret < 0) {
ejsSetErrorMsg(eid, "%s: %s", script, emsg);
return -1;
}
break;
}
talloc_free(path);
}
if (js_include[j] == NULL) {
ejsSetErrorMsg(eid, "unable to include '%s'", script);
return -1;
}
}
return 0;
}
/*
return the current version
*/
static int ejs_version(MprVarHandle eid, int argc, struct MprVar **argv)
{
mpr_ReturnString(eid, SAMBA_VERSION_STRING);
return 0;
}
/*
* jsonrpc_include() allows you to include jsonrpc files from a path based at
* "jsonrpc services directory =" in smb.conf.
*/
static int jsonrpc_include(int eid, int argc, char **argv)
{
int ret = -1;
char *path;
char *emsg;
const char *jsonrpc_services_dir = lp_jsonrpc_services_dir();
struct MprVar result;
if (jsonrpc_services_dir == NULL || jsonrpc_services_dir == NULL) {
ejsSetErrorMsg(eid, "'jsonrpc services directory' not set");
return -1;
}
if (argc != 1) {
mpr_Return(eid, mprCreateIntegerVar(-1));
return 0;
}
path = talloc_asprintf(mprMemCtx(), "%s/%s",
jsonrpc_services_dir,
argv[0]);
if (path == NULL) {
mpr_Return(eid, mprCreateIntegerVar(-1));
return 0;
}
if (file_exist(path)) {
ret = ejsEvalFile(eid, path, &result, &emsg);
if (ret < 0) {
ejsSetErrorMsg(eid, "Could not eval file");
printf("file found; ret=%d (%s)\n", ret, emsg);
}
}
mpr_Return(eid, mprCreateIntegerVar(ret));
talloc_free(path);
return 0;
}
static void (*ejs_exception_handler) (const char *) = NULL;
_PUBLIC_ void ejs_exception(const char *reason)
{
ejs_exception_handler(reason);
}
/*
setup C functions that be called from ejs
*/
void smb_setup_ejs_functions(void (*exception_handler)(const char *))
{
init_module_fn static_init[] = STATIC_smbcalls_MODULES;
init_module_fn *shared_init;
ejs_exception_handler = exception_handler;
smb_setup_ejs_cli();
smb_setup_ejs_options();
smb_setup_ejs_credentials();
smb_setup_ejs_param();
smb_setup_ejs_literal();
ejsnet_setup();
shared_init = load_samba_modules(NULL, "smbcalls");
run_init_functions(static_init);
run_init_functions(shared_init);
talloc_free(shared_init);
ejsDefineCFunction(-1, "typeof", ejs_typeof, NULL, MPR_VAR_SCRIPT_HANDLE);
ejsDefineCFunction(-1, "nativeTypeOf", ejs_typeof_native, NULL, MPR_VAR_SCRIPT_HANDLE);
ejsDefineStringCFunction(-1, "libinclude", ejs_libinclude, NULL, MPR_VAR_SCRIPT_HANDLE);
ejsDefineCFunction(-1, "version", ejs_version, NULL, MPR_VAR_SCRIPT_HANDLE);
ejsDefineStringCFunction(-1, "jsonrpc_include", jsonrpc_include, NULL, MPR_VAR_SCRIPT_HANDLE);
}
+41
View File
@@ -0,0 +1,41 @@
/*
Unix SMB/CIFS implementation.
provide hooks into smbd C calls from ejs scripts
Copyright (C) Andrew Tridgell 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "lib/appweb/ejs/ejs.h"
void mpr_Return(int eid, struct MprVar);
NTSTATUS mprSetVar(struct MprVar *v, const char *name, struct MprVar val);
NTSTATUS mprGetVar(struct MprVar **v, const char *name);
void mprAddArray(struct MprVar *var, int i, struct MprVar v);
void mprSetCFunction(struct MprVar *obj, const char *name, MprCFunction fn);
void mprSetStringCFunction(struct MprVar *obj, const char *name, MprStringCFunction fn);
struct smbcalls_context {
struct event_context *event_ctx;
struct messaging_context *msg_ctx;
};
struct ldb_context;
struct ldb_message;
struct cli_credentials;
#include "scripting/ejs/proto.h"
+209
View File
@@ -0,0 +1,209 @@
/*
Unix SMB/CIFS implementation.
ejs auth functions
Copyright (C) Simo Sorce 2005
Copyright (C) Andrew Tridgell 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "lib/appweb/ejs/ejs.h"
#include "auth/auth.h"
#include "auth/credentials/credentials.h"
#include "scripting/ejs/smbcalls.h"
#include "lib/events/events.h"
#include "lib/messaging/irpc.h"
static int ejs_doauth(MprVarHandle eid,
TALLOC_CTX *tmp_ctx, struct MprVar *auth, const char *username,
const char *password, const char *domain, const char *workstation,
struct socket_address *remote_host, const char **auth_types)
{
struct auth_usersupplied_info *user_info = NULL;
struct auth_serversupplied_info *server_info = NULL;
struct auth_session_info *session_info = NULL;
struct auth_context *auth_context;
struct MprVar *session_info_obj;
NTSTATUS nt_status;
struct smbcalls_context *c;
struct event_context *ev;
struct messaging_context *msg;
/* Hope we can find an smbcalls_context somewhere up there... */
c = talloc_find_parent_bytype(tmp_ctx, struct smbcalls_context);
if (c) {
ev = c->event_ctx;
msg = c->msg_ctx;
} else {
/* Hope we can find the event context somewhere up there... */
ev = event_context_find(tmp_ctx);
msg = messaging_client_init(tmp_ctx, ev);
}
nt_status = auth_context_create(tmp_ctx, auth_types, ev, msg, &auth_context);
if (!NT_STATUS_IS_OK(nt_status)) {
mprSetPropertyValue(auth, "result", mprCreateBoolVar(False));
mprSetPropertyValue(auth, "report", mprString("Auth System Failure"));
goto done;
}
user_info = talloc(tmp_ctx, struct auth_usersupplied_info);
if (!user_info) {
mprSetPropertyValue(auth, "result", mprCreateBoolVar(False));
mprSetPropertyValue(auth, "report", mprString("talloc failed"));
goto done;
}
user_info->mapped_state = True;
user_info->client.account_name = username;
user_info->mapped.account_name = username;
user_info->client.domain_name = domain;
user_info->mapped.domain_name = domain;
user_info->workstation_name = workstation;
user_info->remote_host = remote_host;
user_info->password_state = AUTH_PASSWORD_PLAIN;
user_info->password.plaintext = talloc_strdup(user_info, password);
user_info->flags = USER_INFO_CASE_INSENSITIVE_USERNAME |
USER_INFO_DONT_CHECK_UNIX_ACCOUNT;
user_info->logon_parameters = 0;
nt_status = auth_check_password(auth_context, tmp_ctx, user_info, &server_info);
/* Don't give the game away (any difference between no such
* user and wrong password) */
nt_status = auth_nt_status_squash(nt_status);
if (!NT_STATUS_IS_OK(nt_status)) {
mprSetPropertyValue(auth, "report",
mprString(talloc_strdup(mprMemCtx(), get_friendly_nt_error_msg(nt_status))));
mprSetPropertyValue(auth, "result", mprCreateBoolVar(False));
goto done;
}
nt_status = auth_generate_session_info(tmp_ctx, server_info, &session_info);
if (!NT_STATUS_IS_OK(nt_status)) {
mprSetPropertyValue(auth, "report", mprString("Session Info generation failed"));
mprSetPropertyValue(auth, "result", mprCreateBoolVar(False));
goto done;
}
session_info_obj = mprInitObject(eid, "session_info", 0, NULL);
mprSetPtrChild(session_info_obj, "session_info", session_info);
talloc_steal(mprMemCtx(), session_info);
mprSetProperty(auth, "session_info", session_info_obj);
mprSetPropertyValue(auth, "result", mprCreateBoolVar(server_info->authenticated));
mprSetPropertyValue(auth, "username", mprString(server_info->account_name));
mprSetPropertyValue(auth, "domain", mprString(server_info->domain_name));
done:
return 0;
}
/*
perform user authentication, returning an array of results
*/
static int ejs_userAuth(MprVarHandle eid, int argc, struct MprVar **argv)
{
TALLOC_CTX *tmp_ctx;
const char *username;
const char *password;
const char *domain;
const char *workstation;
struct MprVar auth;
struct cli_credentials *creds;
struct socket_address *remote_host;
const char *auth_types_unix[] = { "unix", NULL };
if (argc != 2 || argv[0]->type != MPR_TYPE_OBJECT || argv[1]->type != MPR_TYPE_OBJECT) {
ejsSetErrorMsg(eid, "userAuth invalid arguments, this function requires an object.");
return -1;
}
/* get credential values from credentials object */
creds = mprGetPtr(argv[0], "creds");
if (creds == NULL) {
ejsSetErrorMsg(eid, "userAuth requires a 'creds' first parameter");
return -1;
}
remote_host = mprGetPtr(argv[1], "socket_address");
if (remote_host == NULL) {
ejsSetErrorMsg(eid, "userAuth requires a socket address second parameter");
return -1;
}
tmp_ctx = talloc_new(mprMemCtx());
username = cli_credentials_get_username(creds);
password = cli_credentials_get_password(creds);
domain = cli_credentials_get_domain(creds);
workstation = cli_credentials_get_workstation(creds);
if (username == NULL || password == NULL || domain == NULL) {
mpr_Return(eid, mprCreateUndefinedVar());
talloc_free(tmp_ctx);
return 0;
}
auth = mprObject("auth");
if (domain && (strcmp("SYSTEM USER", domain) == 0)) {
ejs_doauth(eid, tmp_ctx, &auth, username, password, domain, workstation, remote_host, auth_types_unix);
} else {
ejs_doauth(eid, tmp_ctx, &auth, username, password, domain, workstation, remote_host, lp_auth_methods());
}
mpr_Return(eid, auth);
talloc_free(tmp_ctx);
return 0;
}
/*
initialise credentials ejs object
*/
static int ejs_system_session(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct MprVar *obj = mprInitObject(eid, "session_info", argc, argv);
struct auth_session_info *session_info = system_session(mprMemCtx());
if (session_info == NULL) {
return -1;
}
mprSetPtrChild(obj, "session_info", session_info);
return 0;
}
/*
setup C functions that be called from ejs
*/
NTSTATUS smb_setup_ejs_auth(void)
{
ejsDefineCFunction(-1, "userAuth", ejs_userAuth, NULL, MPR_VAR_SCRIPT_HANDLE);
ejsDefineCFunction(-1, "system_session", ejs_system_session, NULL, MPR_VAR_SCRIPT_HANDLE);
return NT_STATUS_OK;
}
+718
View File
@@ -0,0 +1,718 @@
/*
Unix SMB/CIFS implementation.
provide hooks into smbd C calls from ejs scripts
Copyright (C) Tim Potter 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "scripting/ejs/smbcalls.h"
#include "lib/appweb/ejs/ejs.h"
#include "libcli/raw/libcliraw.h"
#include "libcli/composite/composite.h"
#include "libcli/smb_composite/smb_composite.h"
#include "libcli/libcli.h"
#include "auth/credentials/credentials.h"
#if 0
#include "librpc/gen_ndr/ndr_nbt.h"
/* Connect to a server */
static int ejs_cli_connect(MprVarHandle eid, int argc, char **argv)
{
struct smbcli_socket *sock;
struct smbcli_transport *transport;
struct nbt_name calling, called;
NTSTATUS result;
if (argc != 1) {
ejsSetErrorMsg(eid, "connect invalid arguments");
return -1;
}
/* Socket connect */
sock = smbcli_sock_init(NULL, NULL);
if (!sock) {
ejsSetErrorMsg(eid, "socket initialisation failed");
return -1;
}
if (!smbcli_sock_connect_byname(sock, argv[0], 0)) {
ejsSetErrorMsg(eid, "socket connect failed");
return -1;
}
transport = smbcli_transport_init(sock, sock, False);
if (!transport) {
ejsSetErrorMsg(eid, "transport init failed");
return -1;
}
/* Send a netbios session request */
make_nbt_name_client(&calling, lp_netbios_name());
nbt_choose_called_name(NULL, &called, argv[0], NBT_NAME_SERVER);
if (!smbcli_transport_connect(transport, &calling, &called)) {
ejsSetErrorMsg(eid, "transport establishment failed");
return -1;
}
result = smb_raw_negotiate(transport, lp_maxprotocol());
if (!NT_STATUS_IS_OK(result)) {
mpr_Return(eid, mprNTSTATUS(result));
return 0;
}
/* Return a socket object */
mpr_Return(eid, mprCreatePtrVar(transport));
return 0;
}
/* Perform a session setup:
session_setup(conn, "DOMAIN\\USERNAME%PASSWORD");
session_setup(conn, USERNAME, PASSWORD);
session_setup(conn, DOMAIN, USERNAME, PASSWORD);
session_setup(conn); // anonymous
*/
static int ejs_cli_ssetup(MprVarHandle eid, int argc, MprVar **argv)
{
struct smbcli_transport *transport;
struct smbcli_session *session;
struct smb_composite_sesssetup setup;
struct cli_credentials *creds;
NTSTATUS status;
int result = -1;
/* Argument parsing */
if (argc < 1 || argc > 4) {
ejsSetErrorMsg(eid, "session_setup invalid arguments");
return -1;
}
if (!mprVarIsPtr(argv[0]->type)) {
ejsSetErrorMsg(eid, "first arg is not a connect handle");
return -1;
}
transport = argv[0]->ptr;
creds = cli_credentials_init(transport);
cli_credentials_set_conf(creds);
if (argc == 4) {
/* DOMAIN, USERNAME, PASSWORD form */
if (!mprVarIsString(argv[1]->type)) {
ejsSetErrorMsg(eid, "arg 1 must be a string");
goto done;
}
cli_credentials_set_domain(creds, argv[1]->string,
CRED_SPECIFIED);
if (!mprVarIsString(argv[2]->type)) {
ejsSetErrorMsg(eid, "arg 2 must be a string");
goto done;
}
cli_credentials_set_username(creds, argv[2]->string,
CRED_SPECIFIED);
if (!mprVarIsString(argv[3]->type)) {
ejsSetErrorMsg(eid, "arg 3 must be a string");
goto done;
}
cli_credentials_set_password(creds, argv[3]->string,
CRED_SPECIFIED);
} else if (argc == 3) {
/* USERNAME, PASSWORD form */
if (!mprVarIsString(argv[1]->type)) {
ejsSetErrorMsg(eid, "arg1 must be a string");
goto done;
}
cli_credentials_set_username(creds, argv[1]->string,
CRED_SPECIFIED);
if (!mprVarIsString(argv[2]->type)) {
ejsSetErrorMsg(eid, "arg2 must be a string");
goto done;
}
cli_credentials_set_password(creds, argv[2]->string,
CRED_SPECIFIED);
} else if (argc == 2) {
/* DOMAIN/USERNAME%PASSWORD form */
cli_credentials_parse_string(creds, argv[1]->string,
CRED_SPECIFIED);
} else {
/* Anonymous connection */
cli_credentials_set_anonymous(creds);
}
/* Do session setup */
session = smbcli_session_init(transport, transport, False);
if (!session) {
ejsSetErrorMsg(eid, "session init failed");
return -1;
}
setup.in.sesskey = transport->negotiate.sesskey;
setup.in.capabilities = transport->negotiate.capabilities;
setup.in.credentials = creds;
setup.in.workgroup = lp_workgroup();
status = smb_composite_sesssetup(session, &setup);
if (!NT_STATUS_IS_OK(status)) {
ejsSetErrorMsg(eid, "session_setup: %s", nt_errstr(status));
return -1;
}
session->vuid = setup.out.vuid;
/* Return a session object */
mpr_Return(eid, mprCreatePtrVar(session));
result = 0;
done:
talloc_free(creds);
return result;
}
/* Perform a tree connect
tree_connect(session, SHARE);
*/
static int ejs_cli_tree_connect(MprVarHandle eid, int argc, MprVar **argv)
{
struct smbcli_session *session;
struct smbcli_tree *tree;
union smb_tcon tcon;
TALLOC_CTX *mem_ctx;
NTSTATUS status;
const char *password = "";
/* Argument parsing */
if (argc != 2) {
ejsSetErrorMsg(eid, "tree_connect invalid arguments");
return -1;
}
if (!mprVarIsPtr(argv[0]->type)) {
ejsSetErrorMsg(eid, "first arg is not a session handle");
return -1;
}
session = argv[0]->ptr;
tree = smbcli_tree_init(session, session, False);
if (!tree) {
ejsSetErrorMsg(eid, "tree init failed");
return -1;
}
mem_ctx = talloc_init("tcon");
if (!mem_ctx) {
ejsSetErrorMsg(eid, "talloc_init failed");
return -1;
}
/* Do tree connect */
tcon.generic.level = RAW_TCON_TCONX;
tcon.tconx.in.flags = 0;
if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
tcon.tconx.in.password = data_blob(NULL, 0);
} else if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) {
tcon.tconx.in.password = data_blob_talloc(mem_ctx, NULL, 24);
if (session->transport->negotiate.secblob.length < 8) {
ejsSetErrorMsg(eid, "invalid security blob");
return -1;
}
SMBencrypt(password, session->transport->negotiate.secblob.data, tcon.tconx.in.password.data);
} else {
tcon.tconx.in.password = data_blob_talloc(mem_ctx, password, strlen(password)+1);
}
tcon.tconx.in.path = argv[1]->string;
tcon.tconx.in.device = "?????";
status = smb_tree_connect(tree, mem_ctx, &tcon);
if (!NT_STATUS_IS_OK(status)) {
ejsSetErrorMsg(eid, "tree_connect: %s", nt_errstr(status));
return -1;
}
tree->tid = tcon.tconx.out.tid;
talloc_free(mem_ctx);
mpr_Return(eid, mprCreatePtrVar(tree));
return 0;
}
/* Perform a tree disconnect
tree_disconnect(tree);
*/
static int ejs_cli_tree_disconnect(MprVarHandle eid, int argc, MprVar **argv)
{
struct smbcli_tree *tree;
NTSTATUS status;
/* Argument parsing */
if (argc != 1) {
ejsSetErrorMsg(eid, "tree_disconnect invalid arguments");
return -1;
}
if (!mprVarIsPtr(argv[0]->type)) {
ejsSetErrorMsg(eid, "first arg is not a tree handle");
return -1;
}
tree = argv[0]->ptr;
status = smb_tree_disconnect(tree);
if (!NT_STATUS_IS_OK(status)) {
ejsSetErrorMsg(eid, "tree_disconnect: %s", nt_errstr(status));
return -1;
}
talloc_free(tree);
return 0;
}
/* Perform a ulogoff
session_logoff(session);
*/
static int ejs_cli_session_logoff(MprVarHandle eid, int argc, MprVar **argv)
{
struct smbcli_session *session;
NTSTATUS status;
/* Argument parsing */
if (argc != 1) {
ejsSetErrorMsg(eid, "session_logoff invalid arguments");
return -1;
}
if (!mprVarIsPtr(argv[0]->type)) {
ejsSetErrorMsg(eid, "first arg is not a session handle");
return -1;
}
session = argv[0]->ptr;
status = smb_raw_ulogoff(session);
if (!NT_STATUS_IS_OK(status)) {
ejsSetErrorMsg(eid, "session_logoff: %s", nt_errstr(status));
return -1;
}
talloc_free(session);
return 0;
}
/* Perform a connection close
disconnect(conn);
*/
static int ejs_cli_disconnect(MprVarHandle eid, int argc, MprVar **argv)
{
struct smbcli_sock *sock;
/* Argument parsing */
if (argc != 1) {
ejsSetErrorMsg(eid, "disconnect invalid arguments");
return -1;
}
if (!mprVarIsPtr(argv[0]->type)) {
ejsSetErrorMsg(eid, "first arg is not a connect handle");
return -1;
}
sock = argv[0]->ptr;
talloc_free(sock);
return 0;
}
#endif
/* Perform a tree connect:
tree_handle = tree_connect("\\\\frogurt\\homes", "user%pass");
*/
static int ejs_tree_connect(MprVarHandle eid, int argc, char **argv)
{
struct cli_credentials *creds;
struct smb_composite_connect io;
struct smbcli_tree *tree;
char *hostname, *sharename;
NTSTATUS result;
TALLOC_CTX *mem_ctx;
if (argc != 2) {
ejsSetErrorMsg(eid, "tree_connect(): invalid number of args");
return -1;
}
/* Set up host, share destination */
mem_ctx = talloc_new(mprMemCtx());
smbcli_parse_unc(argv[0], mem_ctx, &hostname, &sharename);
/* Set up credentials */
creds = cli_credentials_init(NULL);
cli_credentials_set_conf(creds);
cli_credentials_parse_string(creds, argv[1], CRED_SPECIFIED);
/* Do connect */
io.in.dest_host = hostname;
io.in.port = 0;
io.in.called_name = strupper_talloc(mem_ctx, hostname);
io.in.service = sharename;
io.in.service_type = "?????";
io.in.credentials = creds;
io.in.fallback_to_anonymous = False;
io.in.workgroup = lp_workgroup();
result = smb_composite_connect(&io, mem_ctx, NULL);
tree = io.out.tree;
talloc_free(mem_ctx);
if (!NT_STATUS_IS_OK(result)) {
mpr_Return(eid, mprNTSTATUS(result));
return 0;
}
mpr_Return(eid, mprCreatePtrVar(tree));
return 0;
}
#define IS_TREE_HANDLE(x) (mprVarIsPtr((x)->type) && \
talloc_check_name((x)->ptr, "struct smbcli_tree"))
/* Perform a tree disconnect:
tree_disconnect(tree_handle);
*/
static int ejs_tree_disconnect(MprVarHandle eid, int argc, MprVar **argv)
{
struct smbcli_tree *tree;
NTSTATUS result;
if (argc != 1) {
ejsSetErrorMsg(eid,
"tree_disconnect(): invalid number of args");
return -1;
}
if (!IS_TREE_HANDLE(argv[0])) {
ejsSetErrorMsg(eid, "first arg is not a tree handle");
return -1;
}
tree = talloc_check_name(argv[0]->ptr, "struct smbcli_tree");
result = smb_tree_disconnect(tree);
mpr_Return(eid, mprNTSTATUS(result));
return 0;
}
/* Create a directory:
result = mkdir(tree_handle, DIRNAME);
*/
static int ejs_mkdir(MprVarHandle eid, int argc, MprVar **argv)
{
struct smbcli_tree *tree;
NTSTATUS result;
if (argc != 2) {
ejsSetErrorMsg(eid, "mkdir(): invalid number of args");
return -1;
}
if (!IS_TREE_HANDLE(argv[0])) {
ejsSetErrorMsg(eid, "first arg is not a tree handle");
return -1;
}
tree = argv[0]->ptr;
if (!mprVarIsString(argv[1]->type)) {
ejsSetErrorMsg(eid, "arg 2 must be a string");
return -1;
}
result = smbcli_mkdir(tree, argv[1]->string);
mpr_Return(eid, mprNTSTATUS(result));
return 0;
}
/* Remove a directory:
result = rmdir(tree_handle, DIRNAME);
*/
static int ejs_rmdir(MprVarHandle eid, int argc, MprVar **argv)
{
struct smbcli_tree *tree;
NTSTATUS result;
if (argc != 2) {
ejsSetErrorMsg(eid, "rmdir(): invalid number of args");
return -1;
}
if (!IS_TREE_HANDLE(argv[0])) {
ejsSetErrorMsg(eid, "first arg is not a tree handle");
return -1;
}
tree = argv[0]->ptr;
if (!mprVarIsString(argv[1]->type)) {
ejsSetErrorMsg(eid, "arg 2 must be a string");
return -1;
}
result = smbcli_rmdir(tree, argv[1]->string);
mpr_Return(eid, mprNTSTATUS(result));
return 0;
}
/* Rename a file or directory:
result = rename(tree_handle, SRCFILE, DESTFILE);
*/
static int ejs_rename(MprVarHandle eid, int argc, MprVar **argv)
{
struct smbcli_tree *tree;
NTSTATUS result;
if (argc != 3) {
ejsSetErrorMsg(eid, "rename(): invalid number of args");
return -1;
}
if (!IS_TREE_HANDLE(argv[0])) {
ejsSetErrorMsg(eid, "first arg is not a tree handle");
return -1;
}
tree = argv[0]->ptr;
if (!mprVarIsString(argv[1]->type)) {
ejsSetErrorMsg(eid, "arg 2 must be a string");
return -1;
}
if (!mprVarIsString(argv[2]->type)) {
ejsSetErrorMsg(eid, "arg 3 must be a string");
return -1;
}
result = smbcli_rename(tree, argv[1]->string, argv[2]->string);
mpr_Return(eid, mprNTSTATUS(result));
return 0;
}
/* Unlink a file or directory:
result = unlink(tree_handle, FILENAME);
*/
static int ejs_unlink(MprVarHandle eid, int argc, MprVar **argv)
{
struct smbcli_tree *tree;
NTSTATUS result;
if (argc != 2) {
ejsSetErrorMsg(eid, "unlink(): invalid number of args");
return -1;
}
if (!IS_TREE_HANDLE(argv[0])) {
ejsSetErrorMsg(eid, "first arg is not a tree handle");
return -1;
}
tree = argv[0]->ptr;
if (!mprVarIsString(argv[1]->type)) {
ejsSetErrorMsg(eid, "arg 2 must be a string");
return -1;
}
result = smbcli_unlink(tree, argv[1]->string);
mpr_Return(eid, mprNTSTATUS(result));
return 0;
}
/* List directory contents
result = list(tree_handle, ARG1, ...);
*/
static void ejs_list_helper(struct clilist_file_info *info, const char *mask,
void *state)
{
MprVar *result = (MprVar *)state;
char idx[16];
mprItoa(result->properties->numDataItems, idx, sizeof(idx));
mprSetVar(result, idx, mprString(info->name));
}
static int ejs_list(MprVarHandle eid, int argc, MprVar **argv)
{
struct smbcli_tree *tree;
char *mask;
uint16_t attribute;
MprVar result;
if (argc != 3) {
ejsSetErrorMsg(eid, "list(): invalid number of args");
return -1;
}
if (!IS_TREE_HANDLE(argv[0])) {
ejsSetErrorMsg(eid, "first arg is not a tree handle");
return -1;
}
tree = argv[0]->ptr;
if (!mprVarIsString(argv[1]->type)) {
ejsSetErrorMsg(eid, "arg 2 must be a string");
return -1;
}
mask = argv[1]->string;
if (!mprVarIsNumber(argv[2]->type)) {
ejsSetErrorMsg(eid, "arg 3 must be a number");
return -1;
}
attribute = mprVarToInteger(argv[2]);
result = mprObject("list");
smbcli_list(tree, mask, attribute, ejs_list_helper, &result);
mpr_Return(eid, result);
return 0;
}
/*
setup C functions that be called from ejs
*/
void smb_setup_ejs_cli(void)
{
ejsDefineStringCFunction(-1, "tree_connect", ejs_tree_connect, NULL, MPR_VAR_SCRIPT_HANDLE);
ejsDefineCFunction(-1, "tree_disconnect", ejs_tree_disconnect, NULL, MPR_VAR_SCRIPT_HANDLE);
ejsDefineCFunction(-1, "mkdir", ejs_mkdir, NULL, MPR_VAR_SCRIPT_HANDLE);
ejsDefineCFunction(-1, "rmdir", ejs_rmdir, NULL, MPR_VAR_SCRIPT_HANDLE);
ejsDefineCFunction(-1, "rename", ejs_rename, NULL, MPR_VAR_SCRIPT_HANDLE);
ejsDefineCFunction(-1, "unlink", ejs_unlink, NULL, MPR_VAR_SCRIPT_HANDLE);
ejsDefineCFunction(-1, "list", ejs_list, NULL, MPR_VAR_SCRIPT_HANDLE);
#if 0
ejsDefineStringCFunction(-1, "connect", ejs_cli_connect, NULL, MPR_VAR_SCRIPT_HANDLE);
ejsDefineCFunction(-1, "session_setup", ejs_cli_ssetup, NULL, MPR_VAR_SCRIPT_HANDLE);
ejsDefineCFunction(-1, "tree_connect", ejs_cli_tree_connect, NULL, MPR_VAR_SCRIPT_HANDLE);
ejsDefineCFunction(-1, "tree_disconnect", ejs_cli_tree_disconnect, NULL, MPR_VAR_SCRIPT_HANDLE);
ejsDefineCFunction(-1, "session_logoff", ejs_cli_session_logoff, NULL, MPR_VAR_SCRIPT_HANDLE);
ejsDefineCFunction(-1, "disconnect", ejs_cli_disconnect, NULL, MPR_VAR_SCRIPT_HANDLE);
#endif
}
@@ -0,0 +1,222 @@
/*
Unix SMB/CIFS implementation.
provide hooks into smbd C calls from ejs scripts
Copyright (C) Andrew Tridgell 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "scripting/ejs/smbcalls.h"
#include "lib/appweb/ejs/ejs.h"
#include "param/loadparm.h"
#include "system/network.h"
#include "lib/socket/netif.h"
/*
return a list of defined services
*/
static int ejs_lpServices(MprVarHandle eid, int argc, char **argv)
{
int i;
const char **list = NULL;
if (argc != 0) return -1;
for (i=0;i<lp_numservices();i++) {
list = str_list_add(list, lp_servicename(i));
}
talloc_steal(mprMemCtx(), list);
mpr_Return(eid, mprList("services", list));
return 0;
}
/*
return a list of parameter categories
*/
static int ejs_lpCategories(MprVarHandle eid, int argc, char **argv)
{
struct parm_struct *parm_table = lp_parm_table();
int i;
const char **list = NULL;
if (argc != 0) return -1;
for (i=0;parm_table[i].label;i++) {
if (parm_table[i].class == P_SEPARATOR) {
list = str_list_add(list, parm_table[i].label);
}
}
talloc_steal(mprMemCtx(), list);
mpr_Return(eid, mprList("categories", list));
return 0;
}
/*
allow access to loadparm variables from inside ejs scripts in swat
can be called in 4 ways:
v = lp.get("type:parm"); gets a parametric variable
v = lp.get("share", "type:parm"); gets a parametric variable on a share
v = lp.get("parm"); gets a global variable
v = lp.get("share", "parm"); gets a share variable
the returned variable is a ejs object. It is an array object for lists.
*/
static int ejs_lpGet(MprVarHandle eid, int argc, char **argv)
{
struct parm_struct *parm = NULL;
void *parm_ptr = NULL;
int i;
if (argc < 1) return -1;
if (argc == 2) {
/* its a share parameter */
int snum = lp_servicenumber(argv[0]);
if (snum == -1) {
return -1;
}
if (strchr(argv[1], ':')) {
/* its a parametric option on a share */
const char *type = talloc_strndup(mprMemCtx(),
argv[1],
strcspn(argv[1], ":"));
const char *option = strchr(argv[1], ':') + 1;
const char *value;
if (type == NULL || option == NULL) return -1;
value = lp_get_parametric(snum, type, option);
if (value == NULL) return -1;
mpr_ReturnString(eid, value);
return 0;
}
parm = lp_parm_struct(argv[1]);
if (parm == NULL || parm->class == P_GLOBAL) {
return -1;
}
parm_ptr = lp_parm_ptr(snum, parm);
} else if (strchr(argv[0], ':')) {
/* its a global parametric option */
const char *type = talloc_strndup(mprMemCtx(),
argv[0], strcspn(argv[0], ":"));
const char *option = strchr(argv[0], ':') + 1;
const char *value;
if (type == NULL || option == NULL) return -1;
value = lp_get_parametric(-1, type, option);
if (value == NULL) return -1;
mpr_ReturnString(eid, value);
return 0;
} else {
/* its a global parameter */
parm = lp_parm_struct(argv[0]);
if (parm == NULL) return -1;
parm_ptr = lp_parm_ptr(-1, parm);
}
if (parm == NULL || parm_ptr == NULL) {
return -1;
}
/* construct and return the right type of ejs object */
switch (parm->type) {
case P_STRING:
case P_USTRING:
mpr_ReturnString(eid, *(char **)parm_ptr);
break;
case P_BOOL:
mpr_Return(eid, mprCreateBoolVar(*(BOOL *)parm_ptr));
break;
case P_INTEGER:
case P_BYTES:
mpr_Return(eid, mprCreateIntegerVar(*(int *)parm_ptr));
break;
case P_ENUM:
for (i=0; parm->enum_list[i].name; i++) {
if (*(int *)parm_ptr == parm->enum_list[i].value) {
mpr_ReturnString(eid, parm->enum_list[i].name);
return 0;
}
}
return -1;
case P_LIST:
mpr_Return(eid, mprList(parm->label, *(const char ***)parm_ptr));
break;
case P_SEP:
return -1;
}
return 0;
}
/*
set a smb.conf parameter. Only sets in memory, not permanent
can be called in 4 ways:
ok = lp.set("parm", "value");
*/
static int ejs_lpSet(MprVarHandle eid, int argc, char **argv)
{
if (argc != 2) {
ejsSetErrorMsg(eid, "lp.set invalid arguments");
return -1;
}
mpr_Return(eid, mprCreateBoolVar(lp_set_cmdline(argv[0], argv[1])));
return 0;
}
/*
reload smb.conf
ok = lp.reload();
*/
static int ejs_lpReload(MprVarHandle eid, int argc, char **argv)
{
BOOL ret = lp_load();
if (ret) {
unload_interfaces();
}
mpr_Return(eid, mprCreateBoolVar(ret));
return 0;
}
/*
initialise loadparm ejs subsystem
*/
static int ejs_loadparm_init(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct MprVar *obj = mprInitObject(eid, "loadparm", argc, argv);
mprSetStringCFunction(obj, "get", ejs_lpGet);
mprSetStringCFunction(obj, "set", ejs_lpSet);
mprSetStringCFunction(obj, "reload", ejs_lpReload);
mprSetStringCFunction(obj, "services", ejs_lpServices);
mprSetStringCFunction(obj, "categories", ejs_lpCategories);
return 0;
}
/*
setup C functions that be called from ejs
*/
NTSTATUS smb_setup_ejs_config(void)
{
ejsDefineCFunction(-1, "loadparm_init", ejs_loadparm_init, NULL, MPR_VAR_SCRIPT_HANDLE);
return NT_STATUS_OK;
}
+288
View File
@@ -0,0 +1,288 @@
/*
Unix SMB/CIFS implementation.
provide hooks credentials calls
Copyright (C) Andrew Tridgell 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "scripting/ejs/smbcalls.h"
#include "lib/appweb/ejs/ejs.h"
#include "lib/cmdline/popt_common.h"
#include "auth/credentials/credentials.h"
/*
helper function to get the local objects credentials ptr
*/
static struct cli_credentials *ejs_creds_get_credentials(int eid)
{
struct cli_credentials *creds = mprGetThisPtr(eid, "creds");
if (creds == NULL) {
ejsSetErrorMsg(eid, "NULL ejs credentials");
}
return creds;
}
/*
get a domain
*/
static int ejs_creds_get_domain(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct cli_credentials *creds = ejs_creds_get_credentials(eid);
mpr_Return(eid, mprString(cli_credentials_get_domain(creds)));
return 0;
}
/*
set a domain
*/
static int ejs_creds_set_domain(MprVarHandle eid, int argc, char **argv)
{
struct cli_credentials *creds = ejs_creds_get_credentials(eid);
if (argc != 1) {
ejsSetErrorMsg(eid, "bad arguments to set_domain");
return -1;
}
cli_credentials_set_domain(creds, argv[0], CRED_SPECIFIED);
mpr_Return(eid, mprCreateBoolVar(True));
return 0;
}
/*
get a username
*/
static int ejs_creds_get_username(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct cli_credentials *creds = ejs_creds_get_credentials(eid);
mpr_Return(eid, mprString(cli_credentials_get_username(creds)));
return 0;
}
/*
set a username
*/
static int ejs_creds_set_username(MprVarHandle eid, int argc, char **argv)
{
struct cli_credentials *creds = ejs_creds_get_credentials(eid);
if (argc != 1) {
ejsSetErrorMsg(eid, "bad arguments to set_username");
return -1;
}
cli_credentials_set_username(creds, argv[0], CRED_SPECIFIED);
mpr_Return(eid, mprCreateBoolVar(True));
return 0;
}
/*
get user password
*/
static int ejs_creds_get_password(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct cli_credentials *creds = ejs_creds_get_credentials(eid);
mpr_Return(eid, mprString(cli_credentials_get_password(creds)));
return 0;
}
/*
set user password
*/
static int ejs_creds_set_password(MprVarHandle eid, int argc, char **argv)
{
struct cli_credentials *creds = ejs_creds_get_credentials(eid);
if (argc != 1) {
ejsSetErrorMsg(eid, "bad arguments to set_password");
return -1;
}
cli_credentials_set_password(creds, argv[0], CRED_SPECIFIED);
mpr_Return(eid, mprCreateBoolVar(True));
return 0;
}
/*
set realm
*/
static int ejs_creds_set_realm(MprVarHandle eid, int argc, char **argv)
{
struct cli_credentials *creds = ejs_creds_get_credentials(eid);
if (argc != 1) {
ejsSetErrorMsg(eid, "bad arguments to set_realm");
return -1;
}
cli_credentials_set_realm(creds, argv[0], CRED_SPECIFIED);
mpr_Return(eid, mprCreateBoolVar(True));
return 0;
}
/*
get realm
*/
static int ejs_creds_get_realm(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct cli_credentials *creds = ejs_creds_get_credentials(eid);
mpr_Return(eid, mprString(cli_credentials_get_realm(creds)));
return 0;
}
/*
set workstation
*/
static int ejs_creds_set_workstation(MprVarHandle eid, int argc, char **argv)
{
struct cli_credentials *creds = ejs_creds_get_credentials(eid);
if (argc != 1) {
ejsSetErrorMsg(eid, "bad arguments to set_workstation");
return -1;
}
cli_credentials_set_workstation(creds, argv[0], CRED_SPECIFIED);
mpr_Return(eid, mprCreateBoolVar(True));
return 0;
}
/*
get workstation
*/
static int ejs_creds_get_workstation(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct cli_credentials *creds = ejs_creds_get_credentials(eid);
mpr_Return(eid, mprString(cli_credentials_get_workstation(creds)));
return 0;
}
/*
set machine account
*/
static int ejs_creds_set_machine_account(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct cli_credentials *creds = ejs_creds_get_credentials(eid);
if (argc != 0) {
ejsSetErrorMsg(eid, "bad arguments to set_machine_account");
return -1;
}
if (NT_STATUS_IS_OK(cli_credentials_set_machine_account(creds))) {
mpr_Return(eid, mprCreateBoolVar(True));
} else {
mpr_Return(eid, mprCreateBoolVar(False));
}
return 0;
}
/*
initialise credentials ejs object
*/
static int ejs_credentials_obj(struct MprVar *obj, struct cli_credentials *creds)
{
mprSetPtrChild(obj, "creds", creds);
/* setup our object methods */
mprSetCFunction(obj, "get_domain", ejs_creds_get_domain);
mprSetStringCFunction(obj, "set_domain", ejs_creds_set_domain);
mprSetCFunction(obj, "get_username", ejs_creds_get_username);
mprSetStringCFunction(obj, "set_username", ejs_creds_set_username);
mprSetCFunction(obj, "get_password", ejs_creds_get_password);
mprSetStringCFunction(obj, "set_password", ejs_creds_set_password);
mprSetCFunction(obj, "get_realm", ejs_creds_get_realm);
mprSetStringCFunction(obj, "set_realm", ejs_creds_set_realm);
mprSetCFunction(obj, "get_workstation", ejs_creds_get_workstation);
mprSetStringCFunction(obj, "set_workstation", ejs_creds_set_workstation);
mprSetCFunction(obj, "set_machine_account", ejs_creds_set_machine_account);
return 0;
}
struct MprVar mprCredentials(struct cli_credentials *creds)
{
struct MprVar mpv = mprObject("credentials");
ejs_credentials_obj(&mpv, creds);
return mpv;
}
/*
initialise credentials ejs object
*/
static int ejs_credentials_init(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct cli_credentials *creds;
struct MprVar *obj = mprInitObject(eid, "credentials", argc, argv);
creds = cli_credentials_init(mprMemCtx());
if (creds == NULL) {
return -1;
}
cli_credentials_set_conf(creds);
return ejs_credentials_obj(obj, creds);
}
/*
initialise cmdline credentials ejs object
*/
int ejs_credentials_cmdline(int eid, int argc, struct MprVar **argv)
{
struct MprVar *obj = mprInitObject(eid, "credentials", argc, argv);
if (talloc_reference(mprMemCtx(), cmdline_credentials) == NULL) {
return -1;
}
return ejs_credentials_obj(obj, cmdline_credentials);
}
static int ejs_credentials_update_all_keytabs(MprVarHandle eid, int argc, struct MprVar **argv)
{
if (!NT_STATUS_IS_OK(cli_credentials_update_all_keytabs(mprMemCtx()))) {
mpr_Return(eid, mprCreateBoolVar(False));
} else {
mpr_Return(eid, mprCreateBoolVar(True));
}
return 0;
}
/*
setup C functions that be called from ejs
*/
void smb_setup_ejs_credentials(void)
{
ejsDefineCFunction(-1, "credentials_init", ejs_credentials_init, NULL, MPR_VAR_SCRIPT_HANDLE);
ejsDefineCFunction(-1, "credentials_update_all_keytabs", ejs_credentials_update_all_keytabs, NULL, MPR_VAR_SCRIPT_HANDLE);
}
+285
View File
@@ -0,0 +1,285 @@
/*
Unix SMB/CIFS implementation.
provide access to data blobs
Copyright (C) Andrew Tridgell 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "scripting/ejs/smbcalls.h"
#include "lib/appweb/ejs/ejs.h"
#include "librpc/gen_ndr/winreg.h"
/*
create a data blob object from a ejs array of integers
*/
static int ejs_blobFromArray(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct MprVar *array, *v;
unsigned length, i;
DATA_BLOB blob;
if (argc != 1) {
ejsSetErrorMsg(eid, "blobFromArray invalid arguments");
return -1;
}
array = argv[0];
v = mprGetProperty(array, "length", NULL);
if (v == NULL) {
goto failed;
}
length = mprToInt(v);
blob = data_blob_talloc(mprMemCtx(), NULL, length);
if (length != 0 && blob.data == NULL) {
goto failed;
}
for (i=0;i<length;i++) {
struct MprVar *vs;
char idx[16];
mprItoa(i, idx, sizeof(idx));
vs = mprGetProperty(array, idx, NULL);
if (vs == NULL) {
goto failed;
}
blob.data[i] = mprVarToNumber(vs);
}
mpr_Return(eid, mprDataBlob(blob));
return 0;
failed:
mpr_Return(eid, mprCreateUndefinedVar());
return 0;
}
/*
create a ejs array of integers from a data blob
*/
static int ejs_blobToArray(MprVarHandle eid, int argc, struct MprVar **argv)
{
DATA_BLOB *blob;
struct MprVar array;
int i;
if (argc != 1) {
ejsSetErrorMsg(eid, "blobToArray invalid arguments");
return -1;
}
blob = mprToDataBlob(argv[0]);
if (blob == NULL) {
goto failed;
}
array = mprArray("array");
for (i=0;i<blob->length;i++) {
mprAddArray(&array, i, mprCreateNumberVar(blob->data[i]));
}
mpr_Return(eid, array);
return 0;
failed:
mpr_Return(eid, mprCreateUndefinedVar());
return 0;
}
/*
compare two data blobs
*/
static int ejs_blobCompare(MprVarHandle eid, int argc, struct MprVar **argv)
{
DATA_BLOB *blob1, *blob2;
BOOL ret = False;
if (argc != 2) {
ejsSetErrorMsg(eid, "blobCompare invalid arguments");
return -1;
}
blob1 = mprToDataBlob(argv[0]);
blob2 = mprToDataBlob(argv[1]);
if (blob1 == blob2) {
ret = True;
goto done;
}
if (blob1 == NULL || blob2 == NULL) {
ret = False;
goto done;
}
if (blob1->length != blob2->length) {
ret = False;
goto done;
}
if (memcmp(blob1->data, blob2->data, blob1->length) != 0) {
ret = False;
goto done;
}
ret = True;
done:
mpr_Return(eid, mprCreateBoolVar(ret));
return 0;
}
/*
convert a blob in winreg format to a mpr variable
usage:
v = data.regToVar(blob, type);
*/
static int ejs_regToVar(MprVarHandle eid, int argc, struct MprVar **argv)
{
DATA_BLOB *blob;
enum winreg_Type type;
struct MprVar v;
if (argc != 2) {
ejsSetErrorMsg(eid, "regToVar invalid arguments");
return -1;
}
blob = mprToDataBlob(argv[0]);
type = mprToInt(argv[1]);
if (blob == NULL) {
ejsSetErrorMsg(eid, "regToVar null data");
return -1;
}
switch (type) {
case REG_NONE:
v = mprCreateUndefinedVar();
break;
case REG_SZ:
case REG_EXPAND_SZ: {
char *s;
ssize_t len;
len = convert_string_talloc(mprMemCtx(), CH_UTF16, CH_UNIX,
blob->data, blob->length, (void **)&s);
if (len == -1) {
ejsSetErrorMsg(eid, "regToVar invalid REG_SZ string");
return -1;
}
v = mprString(s);
talloc_free(s);
break;
}
case REG_DWORD: {
if (blob->length != 4) {
ejsSetErrorMsg(eid, "regToVar invalid REG_DWORD length %ld", (long)blob->length);
return -1;
}
v = mprCreateNumberVar(IVAL(blob->data, 0));
break;
}
case REG_DWORD_BIG_ENDIAN: {
if (blob->length != 4) {
ejsSetErrorMsg(eid, "regToVar invalid REG_DWORD_BIG_ENDIAN length %ld", (long)blob->length);
return -1;
}
v = mprCreateNumberVar(RIVAL(blob->data, 0));
break;
}
case REG_QWORD: {
if (blob->length != 8) {
ejsSetErrorMsg(eid, "regToVar invalid REG_QWORD length %ld", (long)blob->length);
return -1;
}
v = mprCreateNumberVar(BVAL(blob->data, 0));
break;
}
case REG_MULTI_SZ: {
DATA_BLOB b = *blob;
const char **list = NULL;
while (b.length > 0) {
char *s;
ssize_t len;
size_t slen = utf16_len_n(b.data, b.length);
if (slen == 2 && b.length == 2 && SVAL(b.data, 0) == 0) {
break;
}
len = convert_string_talloc(mprMemCtx(), CH_UTF16, CH_UNIX,
b.data, slen, (void **)&s);
if (len == -1) {
ejsSetErrorMsg(eid, "regToVar invalid REG_MULTI_SZ string");
return -1;
}
list = str_list_add(list, s);
talloc_free(s);
talloc_steal(mprMemCtx(), list);
b.data += slen;
b.length -= slen;
}
v = mprList("REG_MULTI_SZ", list);
talloc_free(list);
break;
}
case REG_FULL_RESOURCE_DESCRIPTOR:
case REG_RESOURCE_LIST:
case REG_BINARY:
case REG_RESOURCE_REQUIREMENTS_LIST:
case REG_LINK:
return ejs_blobToArray(eid, 1, argv);
default:
ejsSetErrorMsg(eid, "regToVar invalid type %d", type);
return -1;
}
mpr_Return(eid, v);
return 0;
}
/*
initialise datablob ejs subsystem
*/
static int ejs_datablob_init(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct MprVar *obj = mprInitObject(eid, "datablob", argc, argv);
mprSetCFunction(obj, "blobFromArray", ejs_blobFromArray);
mprSetCFunction(obj, "blobToArray", ejs_blobToArray);
mprSetCFunction(obj, "blobCompare", ejs_blobCompare);
mprSetCFunction(obj, "regToVar", ejs_regToVar);
return 0;
}
/*
setup C functions that be called from ejs
*/
NTSTATUS smb_setup_ejs_datablob(void)
{
ejsDefineCFunction(-1, "datablob_init", ejs_datablob_init, NULL, MPR_VAR_SCRIPT_HANDLE);
return NT_STATUS_OK;
}
+563
View File
@@ -0,0 +1,563 @@
/*
Unix SMB/CIFS implementation.
provide hooks into smbd C calls from ejs scripts
Copyright (C) Andrew Tridgell 2005
Copyright (C) Jelmer Vernooij 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "scripting/ejs/smbcalls.h"
#include "lib/appweb/ejs/ejs.h"
#include "lib/ldb/include/ldb.h"
#include "lib/ldb/include/ldb_errors.h"
#include "db_wrap.h"
/*
get the connected db
*/
static struct ldb_context *ejs_get_ldb_context(int eid)
{
struct ldb_context *ldb = mprGetThisPtr(eid, "db");
if (ldb == NULL) {
ejsSetErrorMsg(eid, "invalid ldb connection");
}
return ldb;
}
/*
perform an ldb search, returning an array of results
syntax:
res = ldb.search("expression");
var attrs = new Array("attr1", "attr2", "attr3");
ldb.search("expression", attrs);
var basedn = "cn=this,dc=is,dc=a,dc=test";
ldb.search("expression", basedn, ldb.SCOPE_SUBTREE, attrs);
*/
static int ejs_ldbSearch(MprVarHandle eid, int argc, struct MprVar **argv)
{
const char **attrs = NULL;
const char *expression;
const char *base = NULL;
struct ldb_dn *basedn = NULL;
int scope = LDB_SCOPE_DEFAULT;
TALLOC_CTX *tmp_ctx = talloc_new(mprMemCtx());
struct ldb_context *ldb;
int ret;
struct ldb_result *res=NULL;
/* validate arguments */
if (argc < 1 || argc > 4) {
ejsSetErrorMsg(eid, "ldb.search invalid number of arguments");
goto failed;
}
if (argc > 3 && argv[3]->type != MPR_TYPE_OBJECT) {
ejsSetErrorMsg(eid, "ldb.search attributes must be an object");
goto failed;
}
ldb = ejs_get_ldb_context(eid);
if (ldb == NULL) {
return -1;
}
expression = mprToString(argv[0]);
if (argc > 1) {
base = mprToString(argv[1]);
/* a null basedn is valid */
}
if (base != NULL) {
basedn = ldb_dn_new(tmp_ctx, ldb, base);
if ( ! ldb_dn_validate(basedn)) {
ejsSetErrorMsg(eid, "ldb.search malformed base dn");
goto failed;
}
}
if (argc > 2) {
scope = mprToInt(argv[2]);
switch (scope) {
case LDB_SCOPE_DEFAULT:
case LDB_SCOPE_BASE:
case LDB_SCOPE_ONELEVEL:
case LDB_SCOPE_SUBTREE:
break; /* ok */
default:
ejsSetErrorMsg(eid, "ldb.search invalid scope");
goto failed;
}
}
if (argc > 3) {
attrs = mprToList(tmp_ctx, argv[3]);
}
ret = ldb_search(ldb, basedn, scope, expression, attrs, &res);
if (ret != LDB_SUCCESS) {
ejsSetErrorMsg(eid, "ldb.search failed - %s", ldb_errstring(ldb));
mpr_Return(eid, mprCreateUndefinedVar());
} else {
mpr_Return(eid, mprLdbArray(ldb, res->msgs, res->count, "ldb_message"));
talloc_free(res);
}
talloc_free(tmp_ctx);
return 0;
failed:
talloc_free(tmp_ctx);
return -1;
}
/*
perform an ldb add or modify
*/
static int ejs_ldbAddModify(MprVarHandle eid, int argc, struct MprVar **argv,
int fn(struct ldb_context *, const struct ldb_message *))
{
const char *ldifstring;
struct ldb_context *ldb;
struct ldb_ldif *ldif;
int ret = 0, count=0;
if (argc != 1) {
ejsSetErrorMsg(eid, "ldb.add/modify invalid arguments");
return -1;
}
ldifstring = mprToString(argv[0]);
if (ldifstring == NULL) {
ejsSetErrorMsg(eid, "ldb.add/modify invalid arguments");
return -1;
}
ldb = ejs_get_ldb_context(eid);
if (ldb == NULL) {
return -1;
}
while ((ldif = ldb_ldif_read_string(ldb, &ldifstring))) {
count++;
ret = fn(ldb, ldif->msg);
talloc_free(ldif);
if (ret != 0) break;
}
if (count == 0) {
ejsSetErrorMsg(eid, "ldb.add/modify invalid ldif");
return -1;
}
mpr_Return(eid, mprCreateBoolVar(ret == 0));
return 0;
}
/*
perform an ldb delete
usage:
ok = ldb.delete(dn);
*/
static int ejs_ldbDelete(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct ldb_dn *dn;
struct ldb_context *ldb;
int ret;
if (argc != 1) {
ejsSetErrorMsg(eid, "ldb.delete invalid arguments");
return -1;
}
ldb = ejs_get_ldb_context(eid);
if (ldb == NULL) {
return -1;
}
dn = ldb_dn_new(ldb, ldb, mprToString(argv[0]));
if ( ! ldb_dn_validate(dn)) {
ejsSetErrorMsg(eid, "ldb.delete malformed dn");
return -1;
}
ret = ldb_delete(ldb, dn);
talloc_free(dn);
mpr_Return(eid, mprCreateBoolVar(ret == 0));
return 0;
}
/*
perform an ldb rename
usage:
ok = ldb.rename(dn1, dn2);
*/
static int ejs_ldbRename(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct ldb_dn *dn1, *dn2;
struct ldb_context *ldb;
int ret;
if (argc != 2) {
ejsSetErrorMsg(eid, "ldb.rename invalid arguments");
return -1;
}
ldb = ejs_get_ldb_context(eid);
if (ldb == NULL) {
return -1;
}
dn1 = ldb_dn_new(ldb, ldb, mprToString(argv[0]));
dn2 = ldb_dn_new(ldb, ldb, mprToString(argv[1]));
if ( ! ldb_dn_validate(dn1) || ! ldb_dn_validate(dn2)) {
ejsSetErrorMsg(eid, "ldb.rename invalid or malformed arguments");
return -1;
}
ret = ldb_rename(ldb, dn1, dn2);
talloc_free(dn1);
talloc_free(dn2);
mpr_Return(eid, mprCreateBoolVar(ret == 0));
return 0;
}
/*
get last error message
usage:
ok = ldb.errstring();
*/
static int ejs_ldbErrstring(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct ldb_context *ldb;
ldb = ejs_get_ldb_context(eid);
if (ldb == NULL) {
return -1;
}
mpr_Return(eid, mprString(ldb_errstring(ldb)));
return 0;
}
/*
base64 encode
usage:
dataout = ldb.encode(datain)
*/
static int ejs_base64encode(MprVarHandle eid, int argc, struct MprVar **argv)
{
char *ret;
if (argc != 1) {
ejsSetErrorMsg(eid, "ldb.base64encode invalid argument count");
return -1;
}
if (argv[0]->type == MPR_TYPE_STRING) {
const char *orig = mprToString(argv[0]);
ret = ldb_base64_encode(mprMemCtx(), orig, strlen(orig));
} else {
DATA_BLOB *blob;
blob = mprToDataBlob(argv[0]);
mprAssert(blob);
ret = ldb_base64_encode(mprMemCtx(), (char *)blob->data, blob->length);
}
if (!ret) {
mpr_Return(eid, mprCreateUndefinedVar());
} else {
mpr_Return(eid, mprString(ret));
}
talloc_free(ret);
return 0;
}
/*
base64 decode
usage:
dataout = ldb.decode(datain)
*/
static int ejs_base64decode(MprVarHandle eid, int argc, struct MprVar **argv)
{
char *tmp;
int ret;
if (argc != 1) {
ejsSetErrorMsg(eid, "ldb.base64encode invalid argument count");
return -1;
}
tmp = talloc_strdup(mprMemCtx(), mprToString(argv[0]));
ret = ldb_base64_decode(tmp);
if (ret == -1) {
mpr_Return(eid, mprCreateUndefinedVar());
} else {
DATA_BLOB blob;
blob.data = (uint8_t *)tmp;
blob.length = ret;
mpr_Return(eid, mprDataBlob(blob));
}
talloc_free(tmp);
return 0;
}
/*
escape a DN
usage:
dataout = ldb.dn_escape(datain)
*/
static int ejs_dn_escape(MprVarHandle eid, int argc, struct MprVar **argv)
{
char *ret;
struct ldb_val val;
if (argc != 1) {
ejsSetErrorMsg(eid, "ldb.dn_escape invalid argument count");
return -1;
}
val = data_blob_string_const(mprToString(argv[0]));
ret = ldb_dn_escape_value(mprMemCtx(), val);
if (ret == NULL) {
mpr_Return(eid, mprCreateUndefinedVar());
} else {
mpr_Return(eid, mprString(ret));
talloc_free(ret);
}
return 0;
}
/*
perform an ldb add
syntax:
ok = ldb.add(ldifstring);
*/
static int ejs_ldbAdd(MprVarHandle eid, int argc, struct MprVar **argv)
{
return ejs_ldbAddModify(eid, argc, argv, ldb_add);
}
/*
perform an ldb modify
syntax:
ok = ldb.modify(ldifstring);
*/
static int ejs_ldbModify(MprVarHandle eid, int argc, struct MprVar **argv)
{
return ejs_ldbAddModify(eid, argc, argv, ldb_modify);
}
/*
connect to a database
usage:
ok = ldb.connect(dbfile);
ok = ldb.connect(dbfile, "modules:modlist");
ldb.credentials or ldb.session_info may be setup first
*/
static int ejs_ldbConnect(MprVarHandle eid, int argc, char **argv)
{
struct ldb_context *ldb;
struct auth_session_info *session_info = NULL;
struct cli_credentials *creds = NULL;
struct MprVar *credentials, *session;
struct MprVar *this = mprGetProperty(ejsGetLocalObject(eid), "this", 0);
const char *dbfile;
if (argc < 1) {
ejsSetErrorMsg(eid, "ldb.connect invalid arguments");
return -1;
}
credentials = mprGetProperty(this, "credentials", NULL);
if (credentials) {
creds = talloc_get_type(mprGetPtr(credentials, "creds"), struct cli_credentials);
}
session = mprGetProperty(this, "session_info", NULL);
if (session) {
session_info = talloc_get_type(mprGetPtr(session, "session_info"), struct auth_session_info);
}
dbfile = argv[0];
ldb = ldb_wrap_connect(mprMemCtx(), dbfile,
session_info, creds,
0, (const char **)(argv+1));
if (ldb == NULL) {
ejsSetErrorMsg(eid, "ldb.connect failed to open %s", dbfile);
}
mprSetThisPtr(eid, "db", ldb);
mpr_Return(eid, mprCreateBoolVar(ldb != NULL));
return 0;
}
/*
close a db connection
*/
static int ejs_ldbClose(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct ldb_context *ldb;
if (argc != 0) {
ejsSetErrorMsg(eid, "ldb.close invalid arguments");
return -1;
}
ldb = ejs_get_ldb_context(eid);
if (ldb == NULL) {
return -1;
}
mprSetThisPtr(eid, "db", NULL);
mpr_Return(eid, mprCreateBoolVar(True));
return 0;
}
/*
start a ldb transaction
usage:
ok = ldb.transaction_start();
*/
static int ejs_ldbTransactionStart(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct ldb_context *ldb;
int ret;
if (argc != 0) {
ejsSetErrorMsg(eid, "ldb.transaction_start invalid arguments");
return -1;
}
ldb = ejs_get_ldb_context(eid);
if (ldb == NULL) {
return -1;
}
ret = ldb_transaction_start(ldb);
mpr_Return(eid, mprCreateBoolVar(ret == 0));
return 0;
}
/*
cancel a ldb transaction
usage:
ok = ldb.transaction_cancel();
*/
static int ejs_ldbTransactionCancel(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct ldb_context *ldb;
int ret;
if (argc != 0) {
ejsSetErrorMsg(eid, "ldb.transaction_cancel invalid arguments");
return -1;
}
ldb = ejs_get_ldb_context(eid);
if (ldb == NULL) {
return -1;
}
ret = ldb_transaction_cancel(ldb);
mpr_Return(eid, mprCreateBoolVar(ret == 0));
return 0;
}
/*
commit a ldb transaction
usage:
ok = ldb.transaction_commit();
*/
static int ejs_ldbTransactionCommit(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct ldb_context *ldb;
int ret;
if (argc != 0) {
ejsSetErrorMsg(eid, "ldb.transaction_commit invalid arguments");
return -1;
}
ldb = ejs_get_ldb_context(eid);
if (ldb == NULL) {
return -1;
}
ret = ldb_transaction_commit(ldb);
mpr_Return(eid, mprCreateBoolVar(ret == 0));
return 0;
}
/*
initialise ldb ejs subsystem
*/
static int ejs_ldb_init(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct MprVar *ldb = mprInitObject(eid, "ldb", argc, argv);
mprSetStringCFunction(ldb, "connect", ejs_ldbConnect);
mprSetCFunction(ldb, "search", ejs_ldbSearch);
mprSetCFunction(ldb, "add", ejs_ldbAdd);
mprSetCFunction(ldb, "modify", ejs_ldbModify);
mprSetCFunction(ldb, "del", ejs_ldbDelete);
mprSetCFunction(ldb, "rename", ejs_ldbRename);
mprSetCFunction(ldb, "errstring", ejs_ldbErrstring);
mprSetCFunction(ldb, "encode", ejs_base64encode);
mprSetCFunction(ldb, "decode", ejs_base64decode);
mprSetCFunction(ldb, "dn_escape", ejs_dn_escape);
mprSetCFunction(ldb, "close", ejs_ldbClose);
mprSetCFunction(ldb, "transaction_start", ejs_ldbTransactionStart);
mprSetCFunction(ldb, "transaction_cancel", ejs_ldbTransactionCancel);
mprSetCFunction(ldb, "transaction_commit", ejs_ldbTransactionCommit);
mprSetVar(ldb, "SCOPE_BASE", mprCreateNumberVar(LDB_SCOPE_BASE));
mprSetVar(ldb, "SCOPE_ONE", mprCreateNumberVar(LDB_SCOPE_ONELEVEL));
mprSetVar(ldb, "SCOPE_SUBTREE", mprCreateNumberVar(LDB_SCOPE_SUBTREE));
mprSetVar(ldb, "SCOPE_DEFAULT", mprCreateNumberVar(LDB_SCOPE_DEFAULT));
return 0;
}
/*
setup C functions that be called from ejs
*/
NTSTATUS smb_setup_ejs_ldb(void)
{
ejsDefineCFunction(-1, "ldb_init", ejs_ldb_init, NULL, MPR_VAR_SCRIPT_HANDLE);
return NT_STATUS_OK;
}
+94
View File
@@ -0,0 +1,94 @@
/*
Unix SMB/CIFS implementation.
provide hooks into smbd C calls from ejs scripts
Copyright (C) Tim Potter 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "scripting/ejs/smbcalls.h"
#include "lib/appweb/ejs/ejs.h"
#include "librpc/gen_ndr/nbt.h"
#include "lib/events/events.h"
#include "libcli/resolve/resolve.h"
/*
look up a netbios name
syntax:
resolveName(result, "frogurt");
resolveName(result, "frogurt", 0x1c);
*/
static int ejs_resolve_name(MprVarHandle eid, int argc, struct MprVar **argv)
{
int result = -1;
struct nbt_name name;
TALLOC_CTX *tmp_ctx = talloc_new(mprMemCtx());
NTSTATUS nt_status;
const char *reply_addr;
/* validate arguments */
if (argc < 2 || argc > 3) {
ejsSetErrorMsg(eid, "resolveName invalid arguments");
goto done;
}
if (argv[0]->type != MPR_TYPE_OBJECT) {
ejsSetErrorMsg(eid, "resolvename invalid arguments");
goto done;
}
if (argv[1]->type != MPR_TYPE_STRING) {
ejsSetErrorMsg(eid, "resolveName invalid arguments");
goto done;
}
if (argc == 2) {
make_nbt_name_client(&name, mprToString(argv[1]));
} else {
if (!mprVarIsNumber(argv[1]->type)) {
ejsSetErrorMsg(eid, "resolveName invalid arguments");
goto done;
}
make_nbt_name(&name, mprToString(argv[1]), mprToInt(argv[2]));
}
result = 0;
nt_status = resolve_name(&name, tmp_ctx, &reply_addr, event_context_find(tmp_ctx));
if (NT_STATUS_IS_OK(nt_status)) {
mprSetPropertyValue(argv[0], "value", mprString(reply_addr));
}
mpr_Return(eid, mprNTSTATUS(nt_status));
done:
talloc_free(tmp_ctx);
return result;
}
/*
setup C functions that be called from ejs
*/
NTSTATUS smb_setup_ejs_nbt(void)
{
ejsDefineCFunction(-1, "resolveName", ejs_resolve_name, NULL, MPR_VAR_SCRIPT_HANDLE);
return NT_STATUS_OK;
}
+161
View File
@@ -0,0 +1,161 @@
/*
Unix SMB/CIFS implementation.
provide access to getpwnam() and related calls
Copyright (C) Andrew Tridgell 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "scripting/ejs/smbcalls.h"
#include "lib/appweb/ejs/ejs.h"
#include "system/passwd.h"
/*
return a struct passwd as an object
*/
static struct MprVar mpr_passwd(struct passwd *pwd)
{
struct MprVar ret;
if (pwd == NULL) {
return mprCreateUndefinedVar();
}
ret = mprObject("passwd");
mprSetVar(&ret, "pw_name", mprString(pwd->pw_name));
mprSetVar(&ret, "pw_passwd", mprString(pwd->pw_passwd));
mprSetVar(&ret, "pw_uid", mprCreateIntegerVar(pwd->pw_uid));
mprSetVar(&ret, "pw_gid", mprCreateIntegerVar(pwd->pw_gid));
mprSetVar(&ret, "pw_gecos", mprString(pwd->pw_gecos));
mprSetVar(&ret, "pw_dir", mprString(pwd->pw_dir));
mprSetVar(&ret, "pw_shell", mprString(pwd->pw_shell));
return ret;
}
/*
return a struct passwd as an object
*/
static struct MprVar mpr_group(struct group *grp)
{
struct MprVar ret;
if (grp == NULL) {
return mprCreateUndefinedVar();
}
ret = mprObject("group");
mprSetVar(&ret, "gr_name", mprString(grp->gr_name));
mprSetVar(&ret, "gr_passwd", mprString(grp->gr_passwd));
mprSetVar(&ret, "gr_gid", mprCreateIntegerVar(grp->gr_gid));
mprSetVar(&ret, "gr_mem", mprList("gr_mem", (const char **)grp->gr_mem));
return ret;
}
/*
usage:
var pw = nss.getpwnam("root");
returns an object containing struct passwd entries
*/
static int ejs_getpwnam(MprVarHandle eid, int argc, struct MprVar **argv)
{
/* validate arguments */
if (argc != 1 || argv[0]->type != MPR_TYPE_STRING) {
ejsSetErrorMsg(eid, "getpwnam invalid arguments");
return -1;
}
mpr_Return(eid, mpr_passwd(getpwnam(mprToString(argv[0]))));
return 0;
}
/*
usage:
var pw = nss.getpwuid(0);
returns an object containing struct passwd entries
*/
static int ejs_getpwuid(MprVarHandle eid, int argc, struct MprVar **argv)
{
/* validate arguments */
if (argc != 1 || !mprVarIsNumber(argv[0]->type)) {
ejsSetErrorMsg(eid, "getpwuid invalid arguments");
return -1;
}
mpr_Return(eid, mpr_passwd(getpwuid(mprToInt(argv[0]))));
return 0;
}
/*
usage:
var pw = nss.getgrnam("users");
returns an object containing struct group entries
*/
static int ejs_getgrnam(MprVarHandle eid, int argc, struct MprVar **argv)
{
/* validate arguments */
if (argc != 1 || argv[0]->type != MPR_TYPE_STRING) {
ejsSetErrorMsg(eid, "getgrnam invalid arguments");
return -1;
}
mpr_Return(eid, mpr_group(getgrnam(mprToString(argv[0]))));
return 0;
}
/*
usage:
var pw = nss.getgrgid(0);
returns an object containing struct group entries
*/
static int ejs_getgrgid(MprVarHandle eid, int argc, struct MprVar **argv)
{
/* validate arguments */
if (argc != 1 || argv[0]->type != MPR_TYPE_STRING) {
ejsSetErrorMsg(eid, "getgrgid invalid arguments");
return -1;
}
mpr_Return(eid, mpr_group(getgrgid(mprToInt(argv[0]))));
return 0;
}
/*
initialise nss ejs subsystem
*/
static int ejs_nss_init(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct MprVar *nss = mprInitObject(eid, "nss", argc, argv);
mprSetCFunction(nss, "getpwnam", ejs_getpwnam);
mprSetCFunction(nss, "getpwuid", ejs_getpwuid);
mprSetCFunction(nss, "getgrnam", ejs_getgrnam);
mprSetCFunction(nss, "getgrgid", ejs_getgrgid);
return 0;
}
/*
setup C functions that be called from ejs
*/
NTSTATUS smb_setup_ejs_nss(void)
{
ejsDefineCFunction(-1, "nss_init", ejs_nss_init, NULL, MPR_VAR_SCRIPT_HANDLE);
return NT_STATUS_OK;
}
@@ -0,0 +1,194 @@
/*
Unix SMB/CIFS implementation.
provide a command line options parsing function for ejs
Copyright (C) Andrew Tridgell 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "lib/cmdline/popt_common.h"
#include "scripting/ejs/smbcalls.h"
/*
usage:
options = GetOptions(argv,
"realm=s",
"enablexx",
"myint=i");
the special options POPT_COMMON_* options are recognised and replaced
with the Samba internal options
resulting parsed options are placed in the options object
additional command line arguments are placed in options.ARGV
*/
static int ejs_GetOptions(MprVarHandle eid, int argc, struct MprVar **argv)
{
poptContext pc;
int opt;
struct {
const char *name;
struct poptOption *table;
const char *description;
} tables[] = {
{ "POPT_AUTOHELP", poptHelpOptions, "Help options:" },
{ "POPT_COMMON_SAMBA", popt_common_samba, "Common Samba options:" },
{ "POPT_COMMON_CONNECTION", popt_common_connection, "Connection options:" },
{ "POPT_COMMON_CREDENTIALS", popt_common_credentials, "Authentication options:" },
{ "POPT_COMMON_VERSION", popt_common_version, "Common Samba options:" }
};
struct MprVar *options = mprInitObject(eid, "options", 0, NULL);
TALLOC_CTX *tmp_ctx = talloc_new(mprMemCtx());
struct poptOption *long_options = NULL;
int i, num_options = 0;
int opt_argc;
const char **opt_argv;
const char **opt_names = NULL;
const int BASE_OPTNUM = 0x100000;
/* validate arguments */
if (argc < 1 || argv[0]->type != MPR_TYPE_OBJECT) {
ejsSetErrorMsg(eid, "GetOptions invalid arguments");
return -1;
}
opt_argv = mprToArray(tmp_ctx, argv[0]);
opt_argc = str_list_length(opt_argv);
long_options = talloc_array(tmp_ctx, struct poptOption, 1);
if (long_options == NULL) {
return -1;
}
/* create the long_options array */
for (i=1;i<argc;i++) {
const char *optstr = mprToString(argv[i]);
int t, opt_type = POPT_ARG_NONE;
const char *s;
if (argv[i]->type != MPR_TYPE_STRING) {
ejsSetErrorMsg(eid, "GetOptions string argument");
return -1;
}
long_options = talloc_realloc(tmp_ctx, long_options,
struct poptOption, num_options+2);
if (long_options == NULL) {
return -1;
}
ZERO_STRUCT(long_options[num_options]);
/* see if its one of the special samba option tables */
for (t=0;t<ARRAY_SIZE(tables);t++) {
if (strcmp(tables[t].name, optstr) == 0) {
break;
}
}
if (t < ARRAY_SIZE(tables)) {
opt_names = str_list_add(opt_names, optstr);
talloc_steal(tmp_ctx, opt_names);
long_options[num_options].argInfo = POPT_ARG_INCLUDE_TABLE;
long_options[num_options].arg = tables[t].table;
long_options[num_options].descrip = tables[t].description;
num_options++;
continue;
}
s = strchr(optstr, '=');
if (s) {
char *name = talloc_strndup(tmp_ctx, optstr, (int)(s-optstr));
opt_names = str_list_add(opt_names, name);
if (s[1] == 's') {
opt_type = POPT_ARG_STRING;
} else if (s[1] == 'i') {
opt_type = POPT_ARG_INT;
} else {
ejsSetErrorMsg(eid, "GetOptions invalid option type");
return -1;
}
talloc_free(name);
} else {
opt_names = str_list_add(opt_names, optstr);
}
talloc_steal(tmp_ctx, opt_names);
if (strlen(opt_names[num_options]) == 1) {
long_options[num_options].shortName = opt_names[num_options][0];
} else {
long_options[num_options].longName = opt_names[num_options];
}
long_options[num_options].argInfo = opt_type;
long_options[num_options].val = num_options + BASE_OPTNUM;
num_options++;
}
ZERO_STRUCT(long_options[num_options]);
pc = poptGetContext("smbscript", opt_argc, opt_argv, long_options, 0);
/* parse the options */
while((opt = poptGetNextOpt(pc)) != -1) {
const char *arg;
if (opt < BASE_OPTNUM || opt >= num_options + BASE_OPTNUM) {
char *err;
err = talloc_asprintf(tmp_ctx, "%s: %s",
poptBadOption(pc, POPT_BADOPTION_NOALIAS),
poptStrerror(opt));
mprSetVar(options, "ERROR", mprString(err));
talloc_free(tmp_ctx);
mpr_Return(eid, mprCreateUndefinedVar());
return 0;
}
opt -= BASE_OPTNUM;
arg = poptGetOptArg(pc);
if (arg == NULL) {
mprSetVar(options, opt_names[opt], mprCreateBoolVar(1));
} else if (long_options[opt].argInfo == POPT_ARG_INT) {
int v = strtol(arg, NULL, 0);
mprSetVar(options, opt_names[opt], mprCreateIntegerVar(v));
} else {
mprSetVar(options, opt_names[opt], mprString(arg));
}
}
/* setup options.argv list */
mprSetVar(options, "ARGV", mprList("ARGV", poptGetArgs(pc)));
poptFreeContext(pc);
talloc_free(tmp_ctx);
/* setup methods */
mprSetCFunction(options, "get_credentials", ejs_credentials_cmdline);
return 0;
}
/*
setup C functions that be called from ejs
*/
void smb_setup_ejs_options(void)
{
ejsDefineCFunction(-1, "GetOptions", ejs_GetOptions, NULL, MPR_VAR_SCRIPT_HANDLE);
}
+260
View File
@@ -0,0 +1,260 @@
/*
Unix SMB/CIFS implementation.
provide hooks into smbd C calls from ejs scripts
Copyright (C) Jelmer Vernooij 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "scripting/ejs/smbcalls.h"
#include "lib/appweb/ejs/ejs.h"
#include "param/param.h"
/*
get parameter
value = param.get("name");
value = param.get("section", "name");
*/
static int ejs_param_get(MprVarHandle eid, int argc, char **argv)
{
struct param_context *ctx;
const char *ret;
if (argc != 1 && argc != 2) {
ejsSetErrorMsg(eid, "param.get invalid argument count");
return -1;
}
ctx = mprGetThisPtr(eid, "param");
mprAssert(ctx);
if (argc == 2) {
ret = param_get_string(ctx, argv[0], argv[1]);
} else {
ret = param_get_string(ctx, NULL, argv[0]);
}
if (ret) {
mpr_Return(eid, mprString(ret));
} else {
mpr_Return(eid, mprCreateUndefinedVar());
}
return 0;
}
/*
get list parameter
ok = param.get_list("name");
ok = param.get_list("section", "name");
*/
static int ejs_param_get_list(MprVarHandle eid, int argc, char **argv)
{
struct param_context *ctx;
const char **ret;
if (argc != 1 && argc != 2) {
ejsSetErrorMsg(eid, "param.get_list invalid argument count");
return -1;
}
ctx = mprGetThisPtr(eid, "param");
mprAssert(ctx);
if (argc == 2) {
ret = param_get_string_list(ctx, argv[0], argv[1], NULL);
} else {
ret = param_get_string_list(ctx, NULL, argv[0], NULL);
}
if (ret != NULL) {
mpr_Return(eid, mprList("array", ret));
} else {
mpr_Return(eid, mprCreateUndefinedVar());
}
return 0;
}
/*
set parameter
ok = param.set("name", "value");
ok = param.set("section", "name", "value");
*/
static int ejs_param_set(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct param_context *ctx;
const char **list;
const char *section, *paramname;
struct MprVar *value;
bool ret;
if (argc != 2 && argc != 3) {
ejsSetErrorMsg(eid, "param.set invalid argument count");
return -1;
}
ctx = mprGetThisPtr(eid, "param");
mprAssert(ctx);
if (argc == 3) {
section = mprToString(argv[0]);
paramname = mprToString(argv[1]);
value = argv[2];
} else {
section = NULL;
paramname = mprToString(argv[0]);
value = argv[1];
}
list = mprToList(mprMemCtx(), value);
if (list) {
ret = param_set_string_list(ctx, section, paramname, list);
} else {
ret = param_set_string(ctx, section, paramname, mprToString(value));
}
mpr_Return(eid, mprCreateBoolVar(ret));
return 0;
}
/*
param data as a two-level array
data = param.data;
*/
static int ejs_param_data(MprVarHandle eid, int argc, char **argv)
{
struct param_context *ctx;
struct MprVar ret;
struct param_section *sec;
if (argc != 0) {
ejsSetErrorMsg(eid, "param.data does not take arguments");
return -1;
}
ctx = mprGetThisPtr(eid, "param");
mprAssert(ctx);
ret = mprObject("array");
for (sec = ctx->sections; sec; sec = sec->next) {
struct MprVar ps = mprObject("array");
struct param *p;
for (p = sec->parameters; p; p = p->next) {
mprSetVar(&ps, p->name, mprString(p->value));
}
mprSetVar(&ret, sec->name, ps);
}
mpr_Return(eid, ret);
return 0;
}
/*
load file
ok = param.load(file);
*/
static int ejs_param_load(MprVarHandle eid, int argc, char **argv)
{
struct param_context *ctx;
bool ret;
if (argc != 1) {
ejsSetErrorMsg(eid, "param.load invalid argument count");
return -1;
}
ctx = mprGetThisPtr(eid, "param");
mprAssert(ctx);
ret = param_read(ctx, argv[0]);
mpr_Return(eid, mprCreateBoolVar(ret));
return 0;
}
/*
save file
ok = param.save(file);
*/
static int ejs_param_save(MprVarHandle eid, int argc, char **argv)
{
struct param_context *ctx;
bool ret;
if (argc != 1) {
ejsSetErrorMsg(eid, "param.save invalid argument count");
return -1;
}
ctx = mprGetThisPtr(eid, "param");
mprAssert(ctx);
ret = param_write(ctx, argv[0]);
mpr_Return(eid, mprCreateBoolVar(ret));
return 0;
}
static void param_add_members(struct MprVar *obj)
{
mprSetStringCFunction(obj, "get", ejs_param_get);
mprSetStringCFunction(obj, "get_list", ejs_param_get_list);
mprSetCFunction(obj, "set", ejs_param_set);
mprSetStringCFunction(obj, "load", ejs_param_load);
mprSetStringCFunction(obj, "save", ejs_param_save);
mprSetStringCFunction(obj, "data", ejs_param_data);
}
/*
initialise param ejs subsystem
*/
static int ejs_param_init(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct MprVar *obj = mprInitObject(eid, "param", argc, argv);
mprSetPtrChild(obj, "param", param_init(mprMemCtx()));
param_add_members(obj);
return 0;
}
struct MprVar mprParam(struct param_context *ctx)
{
struct MprVar mpv = mprObject("param");
mprSetPtrChild(&mpv, "param", ctx);
param_add_members(&mpv);
return mpv;
}
/*
setup C functions that be called from ejs
*/
void smb_setup_ejs_param(void)
{
ejsDefineCFunction(-1, "param_init", ejs_param_init, NULL, MPR_VAR_SCRIPT_HANDLE);
}
+105
View File
@@ -0,0 +1,105 @@
/*
Unix SMB/CIFS implementation.
provide access to randomisation functions
Copyright (C) Andrew Tridgell 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "scripting/ejs/smbcalls.h"
#include "lib/appweb/ejs/ejs.h"
#include "system/passwd.h"
#include "librpc/gen_ndr/ndr_misc.h"
/*
usage:
var i = random();
*/
static int ejs_random(MprVarHandle eid, int argc, struct MprVar **argv)
{
mpr_Return(eid, mprCreateIntegerVar(generate_random()));
return 0;
}
/*
usage:
var s = randpass(len);
*/
static int ejs_randpass(MprVarHandle eid, int argc, struct MprVar **argv)
{
char *s;
if (argc != 1 || !mprVarIsNumber(argv[0]->type)) {
ejsSetErrorMsg(eid, "randpass invalid arguments");
return -1;
}
s = generate_random_str(mprMemCtx(), mprToInt(argv[0]));
mpr_Return(eid, mprString(s));
talloc_free(s);
return 0;
}
/*
usage:
var guid = randguid();
*/
static int ejs_randguid(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct GUID guid = GUID_random();
char *s = GUID_string(mprMemCtx(), &guid);
mpr_Return(eid, mprString(s));
talloc_free(s);
return 0;
}
/*
usage:
var sid = randsid();
*/
static int ejs_randsid(MprVarHandle eid, int argc, struct MprVar **argv)
{
char *s = talloc_asprintf(mprMemCtx(), "S-1-5-21-%8u-%8u-%8u",
(unsigned)generate_random(),
(unsigned)generate_random(),
(unsigned)generate_random());
mpr_Return(eid, mprString(s));
talloc_free(s);
return 0;
}
/*
initialise random ejs subsystem
*/
static int ejs_random_init(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct MprVar *obj = mprInitObject(eid, "random", argc, argv);
mprSetCFunction(obj, "random", ejs_random);
mprSetCFunction(obj, "randpass", ejs_randpass);
mprSetCFunction(obj, "randguid", ejs_randguid);
mprSetCFunction(obj, "randsid", ejs_randsid);
return 0;
}
/*
setup C functions that be called from ejs
*/
NTSTATUS smb_setup_ejs_random(void)
{
ejsDefineCFunction(-1, "random_init", ejs_random_init, NULL, MPR_VAR_SCRIPT_HANDLE);
return NT_STATUS_OK;
}
+380
View File
@@ -0,0 +1,380 @@
/*
Unix SMB/CIFS implementation.
provide interfaces to rpc calls from ejs scripts
Copyright (C) Andrew Tridgell 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "scripting/ejs/smbcalls.h"
#include "lib/appweb/ejs/ejs.h"
#include "librpc/gen_ndr/echo.h"
#include "lib/cmdline/popt_common.h"
#include "lib/messaging/irpc.h"
#include "scripting/ejs/ejsrpc.h"
#include "lib/util/dlinklist.h"
#include "lib/events/events.h"
#include "librpc/rpc/dcerpc_table.h"
#include "auth/credentials/credentials.h"
#include "librpc/rpc/dcerpc.h"
/*
state of a irpc 'connection'
*/
struct ejs_irpc_connection {
const char *server_name;
uint32_t *dest_ids;
struct messaging_context *msg_ctx;
};
/*
messaging clients need server IDs as well ...
*/
#define EJS_ID_BASE 0x30000000
/*
setup a context for talking to a irpc server
example:
status = irpc.connect("smb_server");
*/
static int ejs_irpc_connect(MprVarHandle eid, int argc, char **argv)
{
NTSTATUS status;
int i;
struct event_context *ev;
struct ejs_irpc_connection *p;
struct MprVar *this = mprGetProperty(ejsGetLocalObject(eid), "this", 0);
/* validate arguments */
if (argc != 1) {
ejsSetErrorMsg(eid, "rpc_connect invalid arguments");
return -1;
}
p = talloc(this, struct ejs_irpc_connection);
if (p == NULL) {
return -1;
}
p->server_name = argv[0];
ev = event_context_find(p);
/* create a messaging context, looping as we have no way to
allocate temporary server ids automatically */
for (i=0;i<10000;i++) {
p->msg_ctx = messaging_init(p, EJS_ID_BASE + i, ev);
if (p->msg_ctx) break;
}
if (p->msg_ctx == NULL) {
ejsSetErrorMsg(eid, "irpc_connect unable to create a messaging context");
talloc_free(p);
return -1;
}
p->dest_ids = irpc_servers_byname(p->msg_ctx, p->server_name);
if (p->dest_ids == NULL || p->dest_ids[0] == 0) {
talloc_free(p);
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
} else {
mprSetPtrChild(this, "irpc", p);
status = NT_STATUS_OK;
}
mpr_Return(eid, mprNTSTATUS(status));
return 0;
}
/*
connect to an rpc server
examples:
status = rpc.connect("ncacn_ip_tcp:localhost");
status = rpc.connect("ncacn_ip_tcp:localhost", "pipe_name");
*/
static int ejs_rpc_connect(MprVarHandle eid, int argc, char **argv)
{
const char *binding, *pipe_name;
const struct dcerpc_interface_table *iface;
NTSTATUS status;
struct dcerpc_pipe *p;
struct cli_credentials *creds;
struct event_context *ev;
struct MprVar *this = mprGetProperty(ejsGetLocalObject(eid), "this", 0);
struct MprVar *credentials;
/* validate arguments */
if (argc < 1) {
ejsSetErrorMsg(eid, "rpc_connect invalid arguments");
return -1;
}
binding = argv[0];
if (strchr(binding, ':') == NULL) {
/* its an irpc connect */
return ejs_irpc_connect(eid, argc, argv);
}
if (argc > 1) {
pipe_name = argv[1];
} else {
pipe_name = mprToString(mprGetProperty(this, "pipe_name", NULL));
}
iface = idl_iface_by_name(pipe_name);
if (iface == NULL) {
status = NT_STATUS_OBJECT_NAME_INVALID;
goto done;
}
credentials = mprGetProperty(this, "credentials", NULL);
if (credentials) {
creds = mprGetPtr(credentials, "creds");
} else {
creds = cmdline_credentials;
}
if (creds == NULL) {
creds = cli_credentials_init(mprMemCtx());
cli_credentials_guess(creds);
cli_credentials_set_anonymous(creds);
}
ev = event_context_find(mprMemCtx());
status = dcerpc_pipe_connect(this, &p, binding, iface, creds, ev);
if (!NT_STATUS_IS_OK(status)) goto done;
/* callers don't allocate ref vars in the ejs interface */
p->conn->flags |= DCERPC_NDR_REF_ALLOC;
/* by making the pipe a child of the connection variable, it will
auto close when it goes out of scope in the script */
mprSetPtrChild(this, "pipe", p);
done:
mpr_Return(eid, mprNTSTATUS(status));
return 0;
}
/*
make an irpc call - called via the same interface as rpc
*/
static int ejs_irpc_call(int eid, struct MprVar *io,
const struct dcerpc_interface_table *iface, int callnum,
ejs_pull_function_t ejs_pull, ejs_push_function_t ejs_push)
{
NTSTATUS status;
void *ptr;
struct ejs_rpc *ejs;
const struct dcerpc_interface_call *call;
struct ejs_irpc_connection *p;
struct irpc_request **reqs;
int i, count;
struct MprVar *results;
p = mprGetThisPtr(eid, "irpc");
ejs = talloc(mprMemCtx(), struct ejs_rpc);
if (ejs == NULL) {
status = NT_STATUS_NO_MEMORY;
goto done;
}
call = &iface->calls[callnum];
ejs->eid = eid;
ejs->callname = call->name;
/* allocate the C structure */
ptr = talloc_zero_size(ejs, call->struct_size);
if (ptr == NULL) {
status = NT_STATUS_NO_MEMORY;
goto done;
}
/* convert the mpr object into a C structure */
status = ejs_pull(ejs, io, ptr);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
for (count=0;p->dest_ids[count];count++) /* noop */ ;
/* we need to make a call per server */
reqs = talloc_array(ejs, struct irpc_request *, count);
if (reqs == NULL) {
status = NT_STATUS_NO_MEMORY;
goto done;
}
/* make the actual calls */
for (i=0;i<count;i++) {
reqs[i] = irpc_call_send(p->msg_ctx, p->dest_ids[i],
iface, callnum, ptr, ptr);
if (reqs[i] == NULL) {
status = NT_STATUS_NO_MEMORY;
goto done;
}
talloc_steal(reqs, reqs[i]);
}
mprSetVar(io, "results", mprObject("results"));
results = mprGetProperty(io, "results", NULL);
/* and receive the results, placing them in io.results[i] */
for (i=0;i<count;i++) {
struct MprVar *output;
status = irpc_call_recv(reqs[i]);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
status = ejs_push(ejs, io, ptr);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
/* add to the results array */
output = mprGetProperty(io, "output", NULL);
if (output) {
char idx[16];
mprItoa(i, idx, sizeof(idx));
mprSetProperty(results, idx, output);
mprDeleteProperty(io, "output");
}
}
mprSetVar(results, "length", mprCreateIntegerVar(i));
done:
talloc_free(ejs);
mpr_Return(eid, mprNTSTATUS(status));
if (NT_STATUS_EQUAL(status, NT_STATUS_INTERNAL_ERROR)) {
return -1;
}
return 0;
}
/*
backend code for making an rpc call - this is called from the pidl generated ejs
code
*/
int ejs_rpc_call(int eid, int argc, struct MprVar **argv,
const struct dcerpc_interface_table *iface, int callnum,
ejs_pull_function_t ejs_pull, ejs_push_function_t ejs_push)
{
struct MprVar *io;
struct dcerpc_pipe *p;
NTSTATUS status;
void *ptr;
struct rpc_request *req;
struct ejs_rpc *ejs;
const struct dcerpc_interface_call *call;
if (argc != 1 || argv[0]->type != MPR_TYPE_OBJECT) {
ejsSetErrorMsg(eid, "rpc_call invalid arguments");
return -1;
}
io = argv[0];
if (mprGetThisPtr(eid, "irpc")) {
/* its an irpc call */
return ejs_irpc_call(eid, io, iface, callnum, ejs_pull, ejs_push);
}
/* get the pipe info */
p = mprGetThisPtr(eid, "pipe");
if (p == NULL) {
ejsSetErrorMsg(eid, "rpc_call invalid pipe");
return -1;
}
ejs = talloc(mprMemCtx(), struct ejs_rpc);
if (ejs == NULL) {
status = NT_STATUS_NO_MEMORY;
goto done;
}
call = &iface->calls[callnum];
ejs->eid = eid;
ejs->callname = call->name;
/* allocate the C structure */
ptr = talloc_zero_size(ejs, call->struct_size);
if (ptr == NULL) {
status = NT_STATUS_NO_MEMORY;
goto done;
}
/* convert the mpr object into a C structure */
status = ejs_pull(ejs, io, ptr);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
/* make the actual call */
req = dcerpc_ndr_request_send(p, NULL, iface, callnum, ptr, ptr);
/* if requested, print the structure */
if (p->conn->flags & DCERPC_DEBUG_PRINT_IN) {
ndr_print_function_debug(call->ndr_print, call->name, NDR_IN, ptr);
}
if (req == NULL) {
status = NT_STATUS_NO_MEMORY;
goto done;
}
status = dcerpc_ndr_request_recv(req);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
/* print the 'out' structure, if needed */
if (p->conn->flags & DCERPC_DEBUG_PRINT_OUT) {
ndr_print_function_debug(call->ndr_print, call->name, NDR_OUT, ptr);
}
status = ejs_push(ejs, io, ptr);
done:
talloc_free(ejs);
mpr_Return(eid, mprNTSTATUS(status));
if (NT_STATUS_EQUAL(status, NT_STATUS_INTERNAL_ERROR)) {
return -1;
}
return 0;
}
/*
hook called by generated RPC interfaces at the end of their init routines
used to add generic operations on the pipe
*/
int ejs_rpc_init(struct MprVar *obj, const char *name)
{
dcerpc_table_init();
mprSetStringCFunction(obj, "connect", ejs_rpc_connect);
if (mprGetProperty(obj, "pipe_name", NULL) == NULL) {
mprSetVar(obj, "pipe_name", mprString(name));
}
return 0;
}
@@ -0,0 +1,501 @@
/*
Unix SMB/CIFS implementation.
provide hooks into smbd C calls from ejs scripts
Copyright (C) Jelmer Vernooij 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "scripting/ejs/smbcalls.h"
#include "lib/appweb/ejs/ejs.h"
#include "lib/samba3/samba3.h"
#include "libcli/security/security.h"
#include "librpc/gen_ndr/ndr_misc.h"
static struct MprVar mprRegistry(struct samba3_regdb *reg)
{
struct MprVar mpv = mprObject("registry"), ks, vs, k, v;
int i, j;
ks = mprArray("array");
for (i = 0; i < reg->key_count; i++) {
k = mprObject("regkey");
mprSetVar(&k, "name", mprString(reg->keys[i].name));
vs = mprArray("array");
for (j = 0; j < reg->keys[i].value_count; j++) {
v = mprObject("regval");
mprSetVar(&v, "name", mprString(reg->keys[i].values[j].name));
mprSetVar(&v, "type", mprCreateIntegerVar(reg->keys[i].values[j].type));
mprSetVar(&v, "data", mprDataBlob(reg->keys[i].values[j].data));
mprAddArray(&vs, j, v);
}
mprSetVar(&k, "values", vs);
mprAddArray(&ks, i, k);
}
if (i == 0) {
mprSetVar(&ks, "length", mprCreateIntegerVar(i));
}
mprSetVar(&mpv, "keys", ks);
return mpv;
}
static struct MprVar mprPolicy(struct samba3_policy *pol)
{
struct MprVar mpv = mprObject("policy");
mprSetVar(&mpv, "min_password_length", mprCreateIntegerVar(pol->min_password_length));
mprSetVar(&mpv, "password_history", mprCreateIntegerVar(pol->password_history));
mprSetVar(&mpv, "user_must_logon_to_change_password", mprCreateIntegerVar(pol->user_must_logon_to_change_password));
mprSetVar(&mpv, "maximum_password_age", mprCreateIntegerVar(pol->maximum_password_age));
mprSetVar(&mpv, "minimum_password_age", mprCreateIntegerVar(pol->minimum_password_age));
mprSetVar(&mpv, "lockout_duration", mprCreateIntegerVar(pol->lockout_duration));
mprSetVar(&mpv, "reset_count_minutes", mprCreateIntegerVar(pol->reset_count_minutes));
mprSetVar(&mpv, "bad_lockout_minutes", mprCreateIntegerVar(pol->bad_lockout_minutes));
mprSetVar(&mpv, "disconnect_time", mprCreateIntegerVar(pol->disconnect_time));
mprSetVar(&mpv, "refuse_machine_password_change", mprCreateIntegerVar(pol->refuse_machine_password_change));
return mpv;
}
static struct MprVar mprIdmapDb(struct samba3_idmapdb *db)
{
struct MprVar mpv = mprObject("idmapdb"), mps, mp;
int i;
mprSetVar(&mpv, "user_hwm", mprCreateIntegerVar(db->user_hwm));
mprSetVar(&mpv, "group_hwm", mprCreateIntegerVar(db->group_hwm));
mps = mprArray("array");
for (i = 0; i < db->mapping_count; i++) {
char *tmp;
mp = mprObject("idmap");
mprSetVar(&mp, "IDMAP_GROUP", mprCreateIntegerVar(IDMAP_GROUP));
mprSetVar(&mp, "IDMAP_USER", mprCreateIntegerVar(IDMAP_USER));
mprSetVar(&mp, "type", mprCreateIntegerVar(db->mappings[i].type));
mprSetVar(&mp, "unix_id", mprCreateIntegerVar(db->mappings[i].unix_id));
tmp = dom_sid_string(NULL, db->mappings[i].sid);
mprSetVar(&mp, "sid", mprString(tmp));
talloc_free(tmp);
mprAddArray(&mps, i, mp);
}
if (i == 0) {
mprSetVar(&mpv, "length", mprCreateIntegerVar(i));
}
mprSetVar(&mpv, "mappings", mps);
return mpv;
}
static struct MprVar mprGroupMappings(struct samba3_groupdb *db)
{
struct MprVar mpv = mprArray("array"), g;
int i;
for (i = 0; i < db->groupmap_count; i++) {
char *tmp;
g = mprObject("group");
mprSetVar(&g, "gid", mprCreateIntegerVar(db->groupmappings[i].gid));
tmp = dom_sid_string(NULL, db->groupmappings[i].sid);
mprSetVar(&g, "sid", mprString(tmp));
talloc_free(tmp);
mprSetVar(&g, "sid_name_use", mprCreateIntegerVar(db->groupmappings[i].sid_name_use));
mprSetVar(&g, "nt_name", mprString(db->groupmappings[i].nt_name));
mprSetVar(&g, "comment", mprString(db->groupmappings[i].comment));
mprAddArray(&mpv, i, g);
}
if (i == 0) {
mprSetVar(&mpv, "length", mprCreateIntegerVar(i));
}
return mpv;
}
static struct MprVar mprAliases(struct samba3_groupdb *db)
{
struct MprVar mpv = mprObject("array"), a, am;
int i, j;
for (i = 0; i < db->alias_count; i++) {
char *tmp;
a = mprObject("alias");
tmp = dom_sid_string(NULL, db->aliases[i].sid);
mprSetVar(&a, "sid", mprString(tmp));
talloc_free(tmp);
am = mprArray("array");
for (j = 0; j < db->aliases[i].member_count; j++) {
tmp = dom_sid_string(NULL, db->aliases[i].members[j]);
mprAddArray(&am, j, mprString(tmp));
talloc_free(tmp);
}
mprSetVar(&a, "members", am);
}
if (i == 0) {
mprSetVar(&mpv, "length", mprCreateIntegerVar(i));
}
return mpv;
}
static struct MprVar mprDomainSecrets(struct samba3_domainsecrets *ds)
{
struct MprVar v, e = mprObject("domainsecrets");
char *tmp;
DATA_BLOB blob;
mprSetVar(&e, "name", mprString(ds->name));
tmp = dom_sid_string(NULL, &ds->sid);
mprSetVar(&e, "sid", mprString(tmp));
talloc_free(tmp);
tmp = GUID_string(NULL, &ds->guid);
mprSetVar(&e, "guid", mprString(tmp));
talloc_free(tmp);
mprSetVar(&e, "plaintext_pw", mprString(ds->plaintext_pw));
mprSetVar(&e, "last_change_time", mprCreateIntegerVar(ds->last_change_time));
mprSetVar(&e, "sec_channel_type", mprCreateIntegerVar(ds->sec_channel_type));
v = mprObject("hash_pw");
blob.data = ds->hash_pw.hash;
blob.length = 16;
mprSetVar(&v, "hash", mprDataBlob(blob));
mprSetVar(&v, "mod_time", mprCreateIntegerVar(ds->hash_pw.mod_time));
mprSetVar(&e, "hash_pw", v);
return e;
}
static struct MprVar mprSecrets(struct samba3_secrets *sec)
{
struct MprVar mpv = mprObject("samba3_secrets"), es, e;
int i;
es = mprArray("array");
for (i = 0; i < sec->ldappw_count; i++) {
e = mprObject("ldappw");
mprSetVar(&e, "dn", mprString(sec->ldappws[i].dn));
mprSetVar(&e, "password", mprString(sec->ldappws[i].password));
mprAddArray(&es, i, e);
}
mprSetVar(&mpv, "ldappws", es);
es = mprArray("array");
for (i = 0; i < sec->domain_count; i++) {
mprAddArray(&es, i, mprDomainSecrets(&sec->domains[i]));
}
if (i == 0) {
mprSetVar(&es, "length", mprCreateIntegerVar(i));
}
mprSetVar(&mpv, "domains", es);
es = mprArray("trusted_domains");
for (i = 0; i < sec->trusted_domain_count; i++) {
struct MprVar ns;
char *tmp;
int j;
e = mprObject("trusted_domain");
ns = mprArray("array");
for (j = 0; j < sec->trusted_domains[i].uni_name_len; j++) {
mprAddArray(&ns, j, mprString(sec->trusted_domains[i].uni_name[j]));
}
mprSetVar(&e, "uni_name", ns);
mprSetVar(&e, "pass", mprString(sec->trusted_domains[i].pass));
mprSetVar(&e, "mod_time", mprCreateIntegerVar(sec->trusted_domains[i].mod_time));
tmp = dom_sid_string(NULL, &sec->trusted_domains[i].domain_sid);
mprSetVar(&e, "domains_sid", mprString(tmp));
talloc_free(tmp);
mprAddArray(&es, i, e);
}
if (i == 0) {
mprSetVar(&es, "length", mprCreateIntegerVar(i));
}
mprSetVar(&mpv, "trusted_domains", es);
es = mprArray("array");
for (i = 0; i < sec->afs_keyfile_count; i++) {
struct MprVar ks;
int j;
e = mprObject("afs_keyfile");
mprSetVar(&e, "cell", mprString(sec->afs_keyfiles[i].cell));
ks = mprArray("array");
for (j = 0; j < 8; j++) {
struct MprVar k = mprObject("entry");
DATA_BLOB blob;
mprSetVar(&k, "kvno", mprCreateIntegerVar(sec->afs_keyfiles[i].entry[j].kvno));
blob.data = (uint8_t*)sec->afs_keyfiles[i].entry[j].key;
blob.length = 8;
mprSetVar(&k, "key", mprDataBlob(blob));
mprAddArray(&ks, j, k);
}
mprSetVar(&e, "entry", ks);
mprSetVar(&e, "nkeys", mprCreateIntegerVar(sec->afs_keyfiles[i].nkeys));
mprAddArray(&es, i, e);
}
if (i == 0) {
mprSetVar(&es, "length", mprCreateIntegerVar(i));
}
mprSetVar(&mpv, "afs_keyfiles", es);
mprSetVar(&mpv, "ipc_cred", mprCredentials(sec->ipc_cred));
return mpv;
}
static struct MprVar mprShares(struct samba3 *samba3)
{
struct MprVar mpv = mprArray("array"), s;
int i;
for (i = 0; i < samba3->share_count; i++) {
s = mprObject("share");
mprSetVar(&s, "name", mprString(samba3->shares[i].name));
/* FIXME: secdesc */
mprAddArray(&mpv, i, s);
}
if (i == 0) {
mprSetVar(&mpv, "length", mprCreateIntegerVar(i));
}
return mpv;
}
static struct MprVar mprSamAccounts(struct samba3 *samba3)
{
struct MprVar mpv = mprArray("array"), m;
int i;
for (i = 0; i < samba3->samaccount_count; i++) {
struct samba3_samaccount *a = &samba3->samaccounts[i];
DATA_BLOB blob;
m = mprObject("samba3_samaccount");
mprSetVar(&m, "logon_time", mprCreateIntegerVar(a->logon_time));
mprSetVar(&m, "logoff_time", mprCreateIntegerVar(a->logoff_time));
mprSetVar(&m, "kickoff_time", mprCreateIntegerVar(a->kickoff_time));
mprSetVar(&m, "bad_password_time", mprCreateIntegerVar(a->bad_password_time));
mprSetVar(&m, "pass_last_set_time", mprCreateIntegerVar(a->pass_last_set_time));
mprSetVar(&m, "pass_can_change_time", mprCreateIntegerVar(a->pass_can_change_time));
mprSetVar(&m, "pass_must_change_time", mprCreateIntegerVar(a->pass_must_change_time));
mprSetVar(&m, "user_rid", mprCreateIntegerVar(a->user_rid));
mprSetVar(&m, "group_rid", mprCreateIntegerVar(a->group_rid));
mprSetVar(&m, "acct_ctrl", mprCreateIntegerVar(a->acct_ctrl));
mprSetVar(&m, "logon_divs", mprCreateIntegerVar(a->logon_divs));
mprSetVar(&m, "bad_password_count", mprCreateIntegerVar(a->bad_password_count));
mprSetVar(&m, "logon_count", mprCreateIntegerVar(a->logon_count));
mprSetVar(&m, "username", mprString(a->username));
mprSetVar(&m, "domain", mprString(a->domain));
mprSetVar(&m, "nt_username", mprString(a->nt_username));
mprSetVar(&m, "dir_drive", mprString(a->dir_drive));
mprSetVar(&m, "munged_dial", mprString(a->munged_dial));
mprSetVar(&m, "fullname", mprString(a->fullname));
mprSetVar(&m, "homedir", mprString(a->homedir));
mprSetVar(&m, "logon_script", mprString(a->logon_script));
mprSetVar(&m, "profile_path", mprString(a->profile_path));
mprSetVar(&m, "acct_desc", mprString(a->acct_desc));
mprSetVar(&m, "workstations", mprString(a->workstations));
blob.length = 16;
blob.data = a->lm_pw.hash;
mprSetVar(&m, "lm_pw", mprDataBlob(blob));
blob.data = a->nt_pw.hash;
mprSetVar(&m, "nt_pw", mprDataBlob(blob));
mprAddArray(&mpv, i, m);
}
if (i == 0) {
mprSetVar(&mpv, "length", mprCreateIntegerVar(i));
}
return mpv;
}
static struct MprVar mprWinsEntries(struct samba3 *samba3)
{
struct MprVar mpv = mprArray("array");
int i, j;
for (i = 0; i < samba3->winsdb_count; i++) {
struct MprVar w = mprObject("wins_entry"), ips;
mprSetVar(&w, "name", mprString(samba3->winsdb_entries[i].name));
mprSetVar(&w, "nb_flags", mprCreateIntegerVar(samba3->winsdb_entries[i].nb_flags));
mprSetVar(&w, "type", mprCreateIntegerVar(samba3->winsdb_entries[i].type));
mprSetVar(&w, "ttl", mprCreateIntegerVar(samba3->winsdb_entries[i].ttl));
ips = mprObject("array");
for (j = 0; j < samba3->winsdb_entries[i].ip_count; j++) {
const char *addr;
addr = sys_inet_ntoa(samba3->winsdb_entries[i].ips[j]);
mprAddArray(&ips, j, mprString(addr));
}
mprSetVar(&w, "ips", ips);
mprAddArray(&mpv, i, w);
}
if (i == 0) {
mprSetVar(&mpv, "length", mprCreateIntegerVar(i));
}
return mpv;
}
static int ejs_find_domainsecrets(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct samba3 *samba3 = NULL;
struct samba3_domainsecrets *sec;
if (argc < 1) {
ejsSetErrorMsg(eid, "find_domainsecrets invalid arguments");
return -1;
}
samba3 = mprGetThisPtr(eid, "samba3");
mprAssert(samba3);
sec = samba3_find_domainsecrets(samba3, mprToString(argv[0]));
if (sec == NULL) {
mpr_Return(eid, mprCreateUndefinedVar());
} else {
mpr_Return(eid, mprDomainSecrets(sec));
}
return 0;
}
/*
initialise samba3 ejs subsystem
samba3 = samba3_read(libdir,smbconf)
*/
static int ejs_samba3_read(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct MprVar mpv = mprObject("samba3");
struct samba3 *samba3;
NTSTATUS status;
if (argc < 2) {
ejsSetErrorMsg(eid, "samba3_read invalid arguments");
return -1;
}
status = samba3_read(mprToString(argv[0]), mprToString(argv[1]), mprMemCtx(), &samba3);
if (NT_STATUS_IS_ERR(status)) {
ejsSetErrorMsg(eid, "samba3_read: error");
return -1;
}
mprAssert(samba3);
mprSetPtrChild(&mpv, "samba3", samba3);
mprSetVar(&mpv, "winsentries", mprWinsEntries(samba3));
mprSetVar(&mpv, "samaccounts", mprSamAccounts(samba3));
mprSetVar(&mpv, "shares", mprShares(samba3));
mprSetVar(&mpv, "secrets", mprSecrets(&samba3->secrets));
mprSetVar(&mpv, "groupmappings", mprGroupMappings(&samba3->group));
mprSetVar(&mpv, "aliases", mprAliases(&samba3->group));
mprSetVar(&mpv, "idmapdb", mprIdmapDb(&samba3->idmap));
mprSetVar(&mpv, "policy", mprPolicy(&samba3->policy));
mprSetVar(&mpv, "registry", mprRegistry(&samba3->registry));
mprSetVar(&mpv, "configuration", mprParam(samba3->configuration));
mprSetCFunction(&mpv, "find_domainsecrets", ejs_find_domainsecrets);
mpr_Return(eid, mpv);
return 0;
}
/*
setup C functions that be called from ejs
*/
NTSTATUS smb_setup_ejs_samba3(void)
{
ejsDefineCFunction(-1, "samba3_read", ejs_samba3_read, NULL, MPR_VAR_SCRIPT_HANDLE);
return NT_STATUS_OK;
}
@@ -0,0 +1,530 @@
/*
Unix SMB/CIFS implementation.
provide access to string functions
Copyright (C) Andrew Tridgell 2005
Copyright (C) Jelmer Vernooij 2005 (substr)
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "scripting/ejs/smbcalls.h"
#include "lib/appweb/ejs/ejs.h"
/*
usage:
var len = strlen(str);
*/
static int ejs_strlen(MprVarHandle eid, int argc, char **argv)
{
if (argc != 1) {
ejsSetErrorMsg(eid, "strlen invalid arguments");
return -1;
}
mpr_Return(eid, mprCreateIntegerVar(strlen_m(argv[0])));
return 0;
}
/*
usage:
var s = strlower("UPPER");
*/
static int ejs_strlower(MprVarHandle eid, int argc, char **argv)
{
char *s;
if (argc != 1) {
ejsSetErrorMsg(eid, "strlower invalid arguments");
return -1;
}
s = strlower_talloc(mprMemCtx(), argv[0]);
mpr_Return(eid, mprString(s));
talloc_free(s);
return 0;
}
/*
usage:
var s = strupper("lower");
*/
static int ejs_strupper(MprVarHandle eid, int argc, char **argv)
{
char *s;
if (argc != 1) {
ejsSetErrorMsg(eid, "strupper invalid arguments");
return -1;
}
s = strupper_talloc(mprMemCtx(), argv[0]);
mpr_Return(eid, mprString(s));
talloc_free(s);
return 0;
}
/*
usage:
var s = strstr(string, substring);
*/
static int ejs_strstr(MprVarHandle eid, int argc, char **argv)
{
char *s;
if (argc != 2) {
ejsSetErrorMsg(eid, "strstr invalid arguments");
return -1;
}
s = strstr(argv[0], argv[1]);
mpr_Return(eid, mprString(s));
return 0;
}
/*
usage:
var s = strspn(string, legal_chars_string);
*/
static int ejs_strspn(MprVarHandle eid, int argc, char **argv)
{
int len;
if (argc != 2) {
ejsSetErrorMsg(eid, "strspn invalid arguments");
return -1;
}
len = strspn(argv[0], argv[1]);
mpr_Return(eid, mprCreateIntegerVar(len));
return 0;
}
/*
usage:
list = split(".", "a.foo.bar");
list = split(".", "a.foo.bar", count);
count is an optional count of how many splits to make
NOTE: does not take a regular expression, unlike perl split()
*/
static int ejs_split(MprVarHandle eid, int argc, struct MprVar **argv)
{
const char *separator, *s;
char *p;
struct MprVar ret;
int count = 0, maxcount=0;
TALLOC_CTX *tmp_ctx = talloc_new(mprMemCtx());
if (argc < 2 ||
argv[0]->type != MPR_TYPE_STRING ||
argv[1]->type != MPR_TYPE_STRING) {
ejsSetErrorMsg(eid, "split invalid arguments");
return -1;
}
separator = mprToString(argv[0]);
s = mprToString(argv[1]);
if (argc == 3) {
maxcount = mprToInt(argv[2]);
}
ret = mprArray("list");
while ((p = strstr(s, separator))) {
char *s2 = talloc_strndup(tmp_ctx, s, (int)(p-s));
mprAddArray(&ret, count++, mprString(s2));
talloc_free(s2);
s = p + strlen(separator);
if (maxcount != 0 && count >= maxcount) {
break;
}
}
if (*s) {
mprAddArray(&ret, count++, mprString(s));
}
talloc_free(tmp_ctx);
mpr_Return(eid, ret);
return 0;
}
/*
usage:
str = substr(orig[, start_offset[, length]]);
special cases:
if start_offset < 0 then start_offset+=strlen(orig)
if length < 0 then length+=strlen(orig)-start_offset
(as found in many other languages)
*/
static int ejs_substr(MprVarHandle eid, int argc, struct MprVar **argv)
{
int start_offset = 0;
int length = 0;
const char *orig;
char *target;
if (argc < 1 || argc > 3 ||
argv[0]->type != MPR_TYPE_STRING) {
ejsSetErrorMsg(eid, "substr invalid arguments");
return -1;
}
if (argc == 1) {
mpr_Return(eid, *argv[0]);
return 0;
}
orig = mprToString(argv[0]);
start_offset = mprToInt(argv[1]);
length = strlen(orig);
if (start_offset < 0) start_offset += strlen(orig);
if (start_offset < 0 || start_offset > strlen(orig)) {
ejsSetErrorMsg(eid, "substr arg 2 out of bounds");
return -1;
}
if (argc == 3) {
length = mprToInt(argv[2]);
if (length < 0) length += strlen(orig) - start_offset;
if (length < 0 || length+start_offset > strlen(orig)) {
ejsSetErrorMsg(eid, "substr arg 3 out of bounds");
return -1;
}
}
target = talloc_strndup(mprMemCtx(), orig+start_offset, length);
mpr_Return(eid, mprString(target));
talloc_free(target);
return 0;
}
/*
usage:
str = join("DC=", list);
*/
static int ejs_join(MprVarHandle eid, int argc, struct MprVar **argv)
{
int i;
const char *separator;
char *ret = NULL;
const char **list;
TALLOC_CTX *tmp_ctx = talloc_new(mprMemCtx());
if (argc != 2 ||
argv[0]->type != MPR_TYPE_STRING ||
argv[1]->type != MPR_TYPE_OBJECT) {
ejsSetErrorMsg(eid, "join invalid arguments");
return -1;
}
separator = mprToString(argv[0]);
list = mprToArray(tmp_ctx, argv[1]);
if (list == NULL || list[0] == NULL) {
talloc_free(tmp_ctx);
mpr_Return(eid, mprString(NULL));
return 0;
}
ret = talloc_strdup(tmp_ctx, list[0]);
if (ret == NULL) {
goto failed;
}
for (i=1;list[i];i++) {
ret = talloc_asprintf_append(ret, "%s%s", separator, list[i]);
if (ret == NULL) {
goto failed;
}
}
mpr_Return(eid, mprString(ret));
talloc_free(tmp_ctx);
return 0;
failed:
ejsSetErrorMsg(eid, "out of memory");
return -1;
}
/*
blergh, C certainly makes this hard!
usage:
str = sprintf("i=%d s=%7s", 7, "foo");
*/
typedef char *(*_asprintf_append_t)(char *, const char *, ...);
static int ejs_sprintf(MprVarHandle eid, int argc, struct MprVar **argv)
{
const char *format;
const char *p;
char *ret;
int a = 1;
_asprintf_append_t _asprintf_append;
TALLOC_CTX *tmp_ctx;
if (argc < 1 || argv[0]->type != MPR_TYPE_STRING) {
ejsSetErrorMsg(eid, "sprintf invalid arguments");
return -1;
}
format = mprToString(argv[0]);
tmp_ctx = talloc_new(mprMemCtx());
ret = talloc_strdup(tmp_ctx, "");
/* avoid all the format string warnings */
_asprintf_append = (_asprintf_append_t)talloc_asprintf_append;
/*
hackity hack ...
*/
while ((p = strchr(format, '%'))) {
char *fmt2;
int len, len_count=0;
char *tstr;
ret = talloc_asprintf_append(ret, "%*.*s",
(int)(p-format), (int)(p-format),
format);
if (ret == NULL) goto failed;
format += (int)(p-format);
len = strcspn(p+1, "dxuiofgGpXeEFcs%") + 1;
fmt2 = talloc_strndup(tmp_ctx, p, len+1);
if (fmt2 == NULL) goto failed;
len_count = count_chars(fmt2, '*');
/* find the type string */
tstr = &fmt2[len];
while (tstr > fmt2 && isalpha((unsigned char)tstr[-1])) {
tstr--;
}
if (strcmp(tstr, "%") == 0) {
ret = talloc_asprintf_append(ret, "%%");
if (ret == NULL) {
goto failed;
}
format += len+1;
continue;
}
if (len_count > 2 ||
argc < a + len_count + 1) {
ejsSetErrorMsg(eid, "sprintf: not enough arguments for format");
goto failed;
}
#define FMT_ARG(fn, type) do { \
switch (len_count) { \
case 0: \
ret = _asprintf_append(ret, fmt2, \
(type)fn(argv[a])); \
break; \
case 1: \
ret = _asprintf_append(ret, fmt2, \
(int)mprVarToNumber(argv[a]), \
(type)fn(argv[a+1])); \
break; \
case 2: \
ret = _asprintf_append(ret, fmt2, \
(int)mprVarToNumber(argv[a]), \
(int)mprVarToNumber(argv[a+1]), \
(type)fn(argv[a+2])); \
break; \
} \
a += len_count + 1; \
if (ret == NULL) { \
goto failed; \
} \
} while (0)
if (strcmp(tstr, "s")==0) FMT_ARG(mprToString, const char *);
else if (strcmp(tstr, "c")==0) FMT_ARG(*mprToString, char);
else if (strcmp(tstr, "d")==0) FMT_ARG(mprVarToNumber, int);
else if (strcmp(tstr, "ld")==0) FMT_ARG(mprVarToNumber, long);
else if (strcmp(tstr, "lld")==0) FMT_ARG(mprVarToNumber, long long);
else if (strcmp(tstr, "x")==0) FMT_ARG(mprVarToNumber, int);
else if (strcmp(tstr, "lx")==0) FMT_ARG(mprVarToNumber, long);
else if (strcmp(tstr, "llx")==0) FMT_ARG(mprVarToNumber, long long);
else if (strcmp(tstr, "X")==0) FMT_ARG(mprVarToNumber, int);
else if (strcmp(tstr, "lX")==0) FMT_ARG(mprVarToNumber, long);
else if (strcmp(tstr, "llX")==0) FMT_ARG(mprVarToNumber, long long);
else if (strcmp(tstr, "u")==0) FMT_ARG(mprVarToNumber, int);
else if (strcmp(tstr, "lu")==0) FMT_ARG(mprVarToNumber, long);
else if (strcmp(tstr, "llu")==0) FMT_ARG(mprVarToNumber, long long);
else if (strcmp(tstr, "i")==0) FMT_ARG(mprVarToNumber, int);
else if (strcmp(tstr, "li")==0) FMT_ARG(mprVarToNumber, long);
else if (strcmp(tstr, "lli")==0) FMT_ARG(mprVarToNumber, long long);
else if (strcmp(tstr, "o")==0) FMT_ARG(mprVarToNumber, int);
else if (strcmp(tstr, "lo")==0) FMT_ARG(mprVarToNumber, long);
else if (strcmp(tstr, "llo")==0) FMT_ARG(mprVarToNumber, long long);
else if (strcmp(tstr, "f")==0) FMT_ARG(mprVarToFloat, double);
else if (strcmp(tstr, "lf")==0) FMT_ARG(mprVarToFloat, double);
else if (strcmp(tstr, "g")==0) FMT_ARG(mprVarToFloat, double);
else if (strcmp(tstr, "lg")==0) FMT_ARG(mprVarToFloat, double);
else if (strcmp(tstr, "e")==0) FMT_ARG(mprVarToFloat, double);
else if (strcmp(tstr, "le")==0) FMT_ARG(mprVarToFloat, double);
else if (strcmp(tstr, "E")==0) FMT_ARG(mprVarToFloat, double);
else if (strcmp(tstr, "lE")==0) FMT_ARG(mprVarToFloat, double);
else if (strcmp(tstr, "F")==0) FMT_ARG(mprVarToFloat, double);
else if (strcmp(tstr, "lF")==0) FMT_ARG(mprVarToFloat, double);
else {
ejsSetErrorMsg(eid, "sprintf: unknown format string '%s'", fmt2);
goto failed;
}
format += len+1;
}
ret = talloc_asprintf_append(ret, "%s", format);
mpr_Return(eid, mprString(ret));
talloc_free(tmp_ctx);
return 0;
failed:
talloc_free(tmp_ctx);
return -1;
}
/*
used to build your own print function
str = vsprintf(args);
*/
static int ejs_vsprintf(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct MprVar **args, *len, *v;
int i, ret, length;
if (argc != 1 || argv[0]->type != MPR_TYPE_OBJECT) {
ejsSetErrorMsg(eid, "vsprintf invalid arguments");
return -1;
}
v = argv[0];
len = mprGetProperty(v, "length", NULL);
if (len == NULL) {
ejsSetErrorMsg(eid, "vsprintf takes an array");
return -1;
}
length = mprToInt(len);
args = talloc_array(mprMemCtx(), struct MprVar *, length);
if (args == NULL) {
return -1;
}
for (i=0;i<length;i++) {
char idx[16];
mprItoa(i, idx, sizeof(idx));
args[i] = mprGetProperty(v, idx, NULL);
}
ret = ejs_sprintf(eid, length, args);
talloc_free(args);
return ret;
}
/*
encode a string, replacing all non-alpha with %02x form
*/
static int ejs_encodeURIComponent(MprVarHandle eid, int argc, char **argv)
{
int i, j, count=0;
const char *s;
char *ret;
if (argc != 1) {
ejsSetErrorMsg(eid, "encodeURIComponent invalid arguments");
return -1;
}
s = argv[0];
for (i=0;s[i];i++) {
if (!isalnum(s[i])) count++;
}
ret = talloc_size(mprMemCtx(), i + count*2 + 1);
if (ret == NULL) {
return -1;
}
for (i=j=0;s[i];i++,j++) {
if (!isalnum(s[i])) {
snprintf(ret+j, 4, "%%%02X", (unsigned)s[i]);
j += 2;
} else {
ret[j] = s[i];
}
}
ret[j] = 0;
mpr_Return(eid, mprString(ret));
talloc_free(ret);
return 0;
}
/*
encode a string, replacing all non-alpha of %02x form
*/
static int ejs_decodeURIComponent(MprVarHandle eid, int argc, char **argv)
{
int i, j, count=0;
const char *s;
char *ret;
if (argc != 1) {
ejsSetErrorMsg(eid, "decodeURIComponent invalid arguments");
return -1;
}
s = argv[0];
ret = talloc_size(mprMemCtx(), strlen(s) + 1);
if (ret == NULL) {
return -1;
}
for (i=j=0;s[i];i++,j++) {
if (s[i] == '%') {
unsigned c;
if (sscanf(s+i+1, "%02X", &c) != 1) {
ejsSetErrorMsg(eid, "decodeURIComponent bad format");
return -1;
}
ret[j] = c;
i += 2;
} else {
ret[j] = s[i];
}
if (!isalnum(s[i])) count++;
}
ret[j] = 0;
mpr_Return(eid, mprString(ret));
talloc_free(ret);
return 0;
}
/*
initialise string ejs subsystem
*/
static int ejs_string_init(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct MprVar *obj = mprInitObject(eid, "string", argc, argv);
mprSetCFunction(obj, "substr", ejs_substr);
mprSetStringCFunction(obj, "strlen", ejs_strlen);
mprSetStringCFunction(obj, "strlower", ejs_strlower);
mprSetStringCFunction(obj, "strupper", ejs_strupper);
mprSetStringCFunction(obj, "strstr", ejs_strstr);
mprSetStringCFunction(obj, "strspn", ejs_strspn);
mprSetCFunction(obj, "split", ejs_split);
mprSetCFunction(obj, "join", ejs_join);
mprSetCFunction(obj, "sprintf", ejs_sprintf);
mprSetCFunction(obj, "vsprintf", ejs_vsprintf);
mprSetStringCFunction(obj, "encodeURIComponent", ejs_encodeURIComponent);
mprSetStringCFunction(obj, "decodeURIComponent", ejs_decodeURIComponent);
return 0;
}
/*
setup C functions that be called from ejs
*/
NTSTATUS smb_setup_ejs_string(void)
{
ejsDefineCFunction(-1, "string_init", ejs_string_init, NULL, MPR_VAR_SCRIPT_HANDLE);
return NT_STATUS_OK;
}
+442
View File
@@ -0,0 +1,442 @@
/*
Unix SMB/CIFS implementation.
provide access to system functions
Copyright (C) Andrew Tridgell 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "scripting/ejs/smbcalls.h"
#include "lib/appweb/ejs/ejs.h"
#include "lib/ldb/include/ldb.h"
#include "system/time.h"
#include "system/network.h"
#include "lib/socket/netif.h"
/*
return the list of configured network interfaces
*/
static int ejs_sys_interfaces(MprVarHandle eid, int argc, struct MprVar **argv)
{
int i, count = iface_count();
struct MprVar ret = mprArray("interfaces");
for (i=0;i<count;i++) {
mprAddArray(&ret, i, mprString(iface_n_ip(i)));
}
mpr_Return(eid, ret);
return 0;
}
/*
return the hostname from gethostname()
*/
static int ejs_sys_hostname(MprVarHandle eid, int argc, struct MprVar **argv)
{
char name[200];
if (gethostname(name, sizeof(name)-1) == -1) {
ejsSetErrorMsg(eid, "gethostname failed - %s", strerror(errno));
return -1;
}
mpr_Return(eid, mprString(name));
return 0;
}
/*
return current time as seconds and microseconds
*/
static int ejs_sys_gettimeofday(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct timeval tv = timeval_current();
struct MprVar v = mprObject("timeval");
struct MprVar sec = mprCreateIntegerVar(tv.tv_sec);
struct MprVar usec = mprCreateIntegerVar(tv.tv_usec);
mprCreateProperty(&v, "sec", &sec);
mprCreateProperty(&v, "usec", &usec);
mpr_Return(eid, v);
return 0;
}
/*
return current time as a 64 bit nttime value
*/
static int ejs_sys_nttime(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct timeval tv = timeval_current();
struct MprVar v = mprCreateNumberVar(timeval_to_nttime(&tv));
mpr_Return(eid, v);
return 0;
}
/*
return time as a 64 bit nttime value from a 32 bit time_t value
*/
static int ejs_sys_unix2nttime(MprVarHandle eid, int argc, struct MprVar **argv)
{
NTTIME nt;
struct MprVar v;
if (argc != 1 || !mprVarIsNumber(argv[0]->type)) {
ejsSetErrorMsg(eid, "sys_unix2nttime invalid arguments");
return -1;
}
unix_to_nt_time(&nt, mprVarToNumber(argv[0]));
v = mprCreateNumberVar(nt);
mpr_Return(eid, v);
return 0;
}
/*
return the GMT time represented by the struct tm argument, as a time_t value
*/
static int ejs_sys_gmmktime(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct MprVar *o;
struct tm tm;
if (argc != 1 || !mprVarIsObject(argv[0]->type)) {
ejsSetErrorMsg(eid, "sys_gmmktime invalid arguments");
return -1;
}
o = argv[0];
#define TM_EL(n) tm.n = mprVarToNumber(mprGetProperty(o, #n, NULL))
TM_EL(tm_sec);
TM_EL(tm_min);
TM_EL(tm_hour);
TM_EL(tm_mday);
TM_EL(tm_mon);
TM_EL(tm_year);
TM_EL(tm_wday);
TM_EL(tm_yday);
TM_EL(tm_isdst);
#undef TM_EL
mpr_Return(eid, mprCreateIntegerVar(mktime(&tm)));
return 0;
}
/*
return the given time as a gmtime structure
*/
static int ejs_sys_gmtime(MprVarHandle eid, int argc, struct MprVar **argv)
{
time_t t;
struct MprVar ret;
struct tm *tm;
if (argc != 1 || !mprVarIsNumber(argv[0]->type)) {
ejsSetErrorMsg(eid, "sys_gmtime invalid arguments");
return -1;
}
t = (time_t) mprVarToNumber(argv[0]);
tm = gmtime(&t);
if (tm == NULL) {
mpr_Return(eid, mprCreateUndefinedVar());
return 0;
}
ret = mprObject("gmtime");
#define TM_EL(n) mprSetVar(&ret, #n, mprCreateIntegerVar(tm->n))
TM_EL(tm_sec);
TM_EL(tm_min);
TM_EL(tm_hour);
TM_EL(tm_mday);
TM_EL(tm_mon);
TM_EL(tm_year);
TM_EL(tm_wday);
TM_EL(tm_yday);
TM_EL(tm_isdst);
#undef TM_EL
mpr_Return(eid, ret);
return 0;
}
/*
return the given NT time as a gmtime structure
*/
static int ejs_sys_ntgmtime(MprVarHandle eid, int argc, struct MprVar **argv)
{
time_t t;
struct MprVar ret;
struct tm *tm;
if (argc != 1 || !mprVarIsNumber(argv[0]->type)) {
ejsSetErrorMsg(eid, "sys_ntgmtime invalid arguments");
return -1;
}
t = nt_time_to_unix(mprVarToNumber(argv[0]));
tm = gmtime(&t);
if (tm == NULL) {
mpr_Return(eid, mprCreateUndefinedVar());
return 0;
}
ret = mprObject("gmtime");
#define TM_EL(n) mprSetVar(&ret, #n, mprCreateIntegerVar(tm->n))
TM_EL(tm_sec);
TM_EL(tm_min);
TM_EL(tm_hour);
TM_EL(tm_mday);
TM_EL(tm_mon);
TM_EL(tm_year);
TM_EL(tm_wday);
TM_EL(tm_yday);
TM_EL(tm_isdst);
#undef TM_EL
mpr_Return(eid, ret);
return 0;
}
/*
return a ldap time string from a nttime
*/
static int ejs_sys_ldaptime(MprVarHandle eid, int argc, struct MprVar **argv)
{
char *s;
time_t t;
if (argc != 1 || !mprVarIsNumber(argv[0]->type)) {
ejsSetErrorMsg(eid, "sys_ldaptime invalid arguments");
return -1;
}
t = nt_time_to_unix(mprVarToNumber(argv[0]));
s = ldb_timestring(mprMemCtx(), t);
mpr_Return(eid, mprString(s));
talloc_free(s);
return 0;
}
/*
return a http time string from a nttime
*/
static int ejs_sys_httptime(MprVarHandle eid, int argc, struct MprVar **argv)
{
char *s;
time_t t;
if (argc != 1 || !mprVarIsNumber(argv[0]->type)) {
ejsSetErrorMsg(eid, "sys_httptime invalid arguments");
return -1;
}
t = nt_time_to_unix(mprVarToNumber(argv[0]));
s = http_timestring(mprMemCtx(), t);
mpr_Return(eid, mprString(s));
talloc_free(s);
return 0;
}
/*
unlink a file
ok = sys.unlink(fname);
*/
static int ejs_sys_unlink(MprVarHandle eid, int argc, char **argv)
{
int ret;
if (argc != 1) {
ejsSetErrorMsg(eid, "sys_unlink invalid arguments");
return -1;
}
ret = unlink(argv[0]);
mpr_Return(eid, mprCreateBoolVar(ret == 0));
return 0;
}
/*
load a file as a string
usage:
string = sys.file_load(filename);
*/
static int ejs_sys_file_load(MprVarHandle eid, int argc, char **argv)
{
char *s;
if (argc != 1) {
ejsSetErrorMsg(eid, "sys_file_load invalid arguments");
return -1;
}
s = file_load(argv[0], NULL, mprMemCtx());
mpr_Return(eid, mprString(s));
talloc_free(s);
return 0;
}
/*
save a file from a string
usage:
ok = sys.file_save(filename, str);
*/
static int ejs_sys_file_save(MprVarHandle eid, int argc, char **argv)
{
BOOL ret;
if (argc != 2) {
ejsSetErrorMsg(eid, "sys_file_save invalid arguments");
return -1;
}
ret = file_save(argv[0], argv[1], strlen(argv[1]));
mpr_Return(eid, mprCreateBoolVar(ret));
return 0;
}
/*
return fields of a stat() call
*/
static struct MprVar mpr_stat(struct stat *st)
{
struct MprVar ret;
ret = mprObject("stat");
#define ST_EL(n) mprSetVar(&ret, #n, mprCreateNumberVar(st->n))
ST_EL(st_dev);
ST_EL(st_ino);
ST_EL(st_mode);
ST_EL(st_nlink);
ST_EL(st_uid);
ST_EL(st_gid);
ST_EL(st_rdev);
ST_EL(st_size);
ST_EL(st_blksize);
ST_EL(st_blocks);
ST_EL(st_atime);
ST_EL(st_mtime);
ST_EL(st_ctime);
return ret;
}
/*
usage:
var st = sys.stat(filename);
returns an object containing struct stat elements
*/
static int ejs_sys_stat(MprVarHandle eid, int argc, char **argv)
{
struct stat st;
/* validate arguments */
if (argc != 1) {
ejsSetErrorMsg(eid, "sys.stat invalid arguments");
return -1;
}
if (stat(argv[0], &st) != 0) {
mpr_Return(eid, mprCreateUndefinedVar());
} else {
mpr_Return(eid, mpr_stat(&st));
}
return 0;
}
/*
usage:
var st = sys.lstat(filename);
returns an object containing struct stat elements
*/
static int ejs_sys_lstat(MprVarHandle eid, int argc, char **argv)
{
struct stat st;
/* validate arguments */
if (argc != 1) {
ejsSetErrorMsg(eid, "sys.stat invalid arguments");
return -1;
}
if (lstat(argv[0], &st) != 0) {
mpr_Return(eid, mprCreateUndefinedVar());
} else {
mpr_Return(eid, mpr_stat(&st));
}
return 0;
}
/*
bitwise AND
usage:
var z = sys.bitAND(x, 0x70);
*/
static int ejs_sys_bitAND(MprVarHandle eid, int argc, struct MprVar **argv)
{
int x, y, z;
if (argc != 2 ||
!mprVarIsNumber(argv[0]->type) ||
!mprVarIsNumber(argv[1]->type)) {
ejsSetErrorMsg(eid, "bitand invalid arguments");
return -1;
}
x = mprToInt(argv[0]);
y = mprToInt(argv[1]);
z = x & y;
mpr_Return(eid, mprCreateIntegerVar(z));
return 0;
}
/*
bitwise OR
usage:
var z = sys.bitOR(x, 0x70);
*/
static int ejs_sys_bitOR(MprVarHandle eid, int argc, struct MprVar **argv)
{
int x, y, z;
if (argc != 2 ||
!mprVarIsNumber(argv[0]->type) ||
!mprVarIsNumber(argv[1]->type)) {
ejsSetErrorMsg(eid, "bitand invalid arguments");
return -1;
}
x = mprToInt(argv[0]);
y = mprToInt(argv[1]);
z = x | y;
mpr_Return(eid, mprCreateIntegerVar(z));
return 0;
}
/*
initialise sys ejs subsystem
*/
static int ejs_sys_init(MprVarHandle eid, int argc, struct MprVar **argv)
{
struct MprVar *obj = mprInitObject(eid, "sys", argc, argv);
mprSetCFunction(obj, "interfaces", ejs_sys_interfaces);
mprSetCFunction(obj, "hostname", ejs_sys_hostname);
mprSetCFunction(obj, "nttime", ejs_sys_nttime);
mprSetCFunction(obj, "gettimeofday", ejs_sys_gettimeofday);
mprSetCFunction(obj, "unix2nttime", ejs_sys_unix2nttime);
mprSetCFunction(obj, "gmmktime", ejs_sys_gmmktime);
mprSetCFunction(obj, "gmtime", ejs_sys_gmtime);
mprSetCFunction(obj, "ntgmtime", ejs_sys_ntgmtime);
mprSetCFunction(obj, "ldaptime", ejs_sys_ldaptime);
mprSetCFunction(obj, "httptime", ejs_sys_httptime);
mprSetStringCFunction(obj, "unlink", ejs_sys_unlink);
mprSetStringCFunction(obj, "file_load", ejs_sys_file_load);
mprSetStringCFunction(obj, "file_save", ejs_sys_file_save);
mprSetStringCFunction(obj, "stat", ejs_sys_stat);
mprSetStringCFunction(obj, "lstat", ejs_sys_lstat);
mprSetCFunction(obj, "bitAND", ejs_sys_bitAND);
mprSetCFunction(obj, "bitOR", ejs_sys_bitOR);
return 0;
}
/*
setup C functions that be called from ejs
*/
NTSTATUS smb_setup_ejs_system(void)
{
ejsDefineCFunction(-1, "sys_init", ejs_sys_init, NULL, MPR_VAR_SCRIPT_HANDLE);
return NT_STATUS_OK;
}
+123
View File
@@ -0,0 +1,123 @@
/*
Unix SMB/CIFS implementation.
Standalone client for ejs scripting.
Copyright (C) Tim Potter <tpot@samba.org> 2005
Copyright (C) Andrew Tridgell 2005
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "lib/appweb/ejs/ejs.h"
#include "lib/appweb/ejs/ejsInternal.h"
#include "scripting/ejs/smbcalls.h"
#include "auth/gensec/gensec.h"
#include "ldb/include/ldb.h"
static EjsId eid;
static void smbscript_ejs_exception(const char *reason)
{
Ejs *ep = ejsPtr(eid);
ejsSetErrorMsg(eid, "%s", reason);
fprintf(stderr, "%s", ep->error);
exit(127);
}
int main(int argc, const char **argv)
{
EjsHandle handle = 0;
MprVar result;
char *emsg, *script;
size_t script_size;
TALLOC_CTX *mem_ctx = talloc_new(NULL);
const char **argv_list = NULL;
const char *fname;
struct MprVar *return_var;
int exit_status, i;
fault_setup(argv[0]);
ldb_global_init();
gensec_init();
mprSetCtx(mem_ctx);
lp_load();
if (argc < 2) {
fprintf(stderr, "You must supply a script name\n");
exit(1);
}
fname = argv[1];
if (ejsOpen(NULL, NULL, NULL) != 0) {
fprintf(stderr, "smbscript: ejsOpen(): unable to initialise "
"EJS subsystem\n");
exit(127);
}
smb_setup_ejs_functions(smbscript_ejs_exception);
if ((eid = ejsOpenEngine(handle, 0)) == (EjsId)-1) {
fprintf(stderr, "smbscript: ejsOpenEngine(): unable to "
"initialise an EJS engine\n");
exit(127);
}
/* setup ARGV[] in the ejs environment */
for (i=1;argv[i];i++) {
argv_list = str_list_add(argv_list, argv[i]);
}
talloc_steal(mem_ctx, argv_list);
mprSetVar(ejsGetGlobalObject(eid), "ARGV", mprList("ARGV", argv_list));
/* load the script and advance past interpreter line*/
script = file_load(fname, &script_size, mem_ctx);
if (!script) {
fprintf(stderr, "Unable to load script from '%s'\n", fname);
exit(1);
}
/* allow scriptable js */
if (strncmp(script, "#!", 2) == 0) {
script += strcspn(script, "\r\n");
script += strspn(script, "\r\n");
}
/* and this copes with the ugly exec hack */
if (strncmp(script, "exec ", 5) == 0) {
script += strcspn(script, "\r\n");
script += strspn(script, "\r\n");
}
/* run the script */
if (ejsEvalScript(eid, script, &result, &emsg) == -1) {
fprintf(stderr, "smbscript: ejsEvalScript(): %s\n", emsg);
exit(127);
}
return_var = ejsGetReturnValue(eid);
exit_status = mprVarToNumber(return_var);
ejsClose();
talloc_free(mem_ctx);
return exit_status;
}
+18
View File
@@ -0,0 +1,18 @@
/*
auth js library functions
Copyright Andrew Tridgell 2005
released under the GNU GPL v2 or later
*/
/*
get a list of domains for SWAT authentication
*/
function getDomainList()
{
var ret = new Array(2);
var lp = loadparm_init();
ret[0] = "System User";
ret[1] = lp.get("workgroup");
return ret;
}
+103
View File
@@ -0,0 +1,103 @@
/*
base js library functions
Copyright Andrew Tridgell 2005
released under the GNU GPL v2 or later
*/
if (global["HAVE_BASE_JS"] != undefined) {
return;
}
HAVE_BASE_JS=1
/* bring the string functions into the global frame */
string_init(global);
/*
an essential function!
*/
function printf()
{
print(vsprintf(arguments));
}
/*
helper function to setup a rpc io object, ready for input
*/
function irpcObj()
{
var o = new Object();
o.input = new Object();
return o;
}
/*
check that a status result is OK
*/
function check_status_ok(status)
{
if (status.is_ok != true) {
printVars(status);
}
assert(status.is_ok == true);
}
/*
check that two arrays are equal
*/
function check_array_equal(a1, a2)
{
assert(a1.length == a2.length);
for (i=0; i<a1.length; i++) {
assert(a1[i] == a2[i]);
}
}
/*
check that an array is all zeros
*/
function check_array_zero(a)
{
for (i=0; i<a.length; i++) {
assert(a[i] == 0);
}
}
/*
substitute strings of the form ${NAME} in str, replacing
with substitutions from subobj
*/
function substitute_var(str, subobj)
{
var list = split("${", str);
var i;
for (i=1;i<list.length;i++) {
var list2 = split("}", list[i], 1);
if ((list2.length < 2) && (list2[0] + "}" != list[i])) {
return undefined;
}
var key = list2[0];
var val;
if (typeof(subobj[key]) == "undefined") {
val = "${" + key + "}";
} else if (typeof(subobj[key]) == "string") {
val = subobj[key];
} else {
var fn = subobj[key];
val = fn(key);
}
list2[0] = "" + val;
list[i] = join("", list2);
}
return join("", list);
}
/*
return "s" if a number should be shown as plural
*/
function plural(n)
{
if (n == 1) {
return "";
}
return "s";
}
+116
View File
@@ -0,0 +1,116 @@
/*
server side js functions for encoding/decoding objects into linear strings
Copyright Andrew Tridgell 2005
released under the GNU GPL Version 2 or later
*/
/*
usage:
enc = encodeObject(obj);
obj = decodeObject(enc);
The encoded format of the object is a string that is safe to
use in URLs
Note that only data elements are encoded, not functions
*/
function __count_members(o) {
var i, count = 0;
for (i in o) {
count++;
}
if (o.length != undefined) {
count++;
}
return count;
}
function __replace(str, old, rep) {
var s = string_init();
var a = s.split(old, str);
var j = s.join(rep, a);
return s.join(rep, a);
}
function encodeElement(e, name) {
var t = typeof(e);
var r;
var s = string_init();
if (t == 'object' && e == null) {
t = 'null';
}
if (t == 'object') {
r = s.sprintf("%s:%s:%s", name, t, encodeObject(e));
} else if (t == "string") {
var enc = s.encodeURIComponent(e);
var rep = __replace(enc, '%', '#');
r = s.sprintf("%s:%s:%s:",
name, t, __replace(s.encodeURIComponent(e),'%','#'));
} else if (t == "boolean" || t == "number") {
r = s.sprintf("%s:%s:%s:", name, t, "" + e);
} else if (t == "undefined" || t == "null") {
r = s.sprintf("%s:%s:", name, t);
} else if (t == "pointer") {
r = s.sprintf("%s:string:(POINTER):", name);
} else {
println("Unable to linearise type " + t);
r = "";
}
return r;
}
function encodeObject(o) {
var s = string_init();
var i, r = s.sprintf("%u:", __count_members(o));
for (i in o) {
r = r + encodeElement(o[i], i);
}
if (o.length != undefined) {
r = r + encodeElement(o.length, 'length');
}
return r;
}
function decodeObjectArray(a) {
var s = string_init();
var o = new Object();
var i, count = a[a.i]; a.i++;
for (i=0;i<count;i++) {
var name = a[a.i]; a.i++;
var type = a[a.i]; a.i++;
var value;
if (type == 'object') {
o[name] = decodeObjectArray(a);
} else if (type == "string") {
value = s.decodeURIComponent(__replace(a[a.i],'#','%')); a.i++;
o[name] = value;
} else if (type == "boolean") {
value = a[a.i]; a.i++;
if (value == 'true') {
o[name] = true;
} else {
o[name] = false;
}
} else if (type == "undefined") {
o[name] = undefined;
} else if (type == "null") {
o[name] = null;
} else if (type == "number") {
value = a[a.i]; a.i++;
o[name] = value + 0;
} else {
println("Unable to delinearise type " + t);
assert(t == "supported type");
}
}
return o;
}
function decodeObject(str) {
var s = string_init();
var a = s.split(':', str);
a.i = 0;
return decodeObjectArray(a);
}
+157
View File
@@ -0,0 +1,157 @@
/*
backend code for Samba4 management
Copyright Andrew Tridgell 2005
Released under the GNU GPL v2 or later
*/
/*
return a list of current sessions
*/
function smbsrv_sessions()
{
var irpc = irpc_init();
status = irpc.connect("smb_server");
if (status.is_ok != true) {
return undefined;
}
var io = irpcObj();
io.input.level = irpc.SMBSRV_INFO_SESSIONS;
status = irpc.smbsrv_information(io);
if (status.is_ok != true) {
return undefined;
}
/* gather the results into a single array */
var i, count=0, ret = new Array(0);
for (i=0;i<io.results.length;i++) {
var sessions = io.results[i].info.sessions.sessions;
var j;
for (j=0;j<sessions.length;j++) {
ret[count] = sessions[j];
count++;
}
}
return ret;
}
/*
return a list of current tree connects
*/
function smbsrv_tcons()
{
var irpc = irpc_init();
status = irpc.connect("smb_server");
if (status.is_ok != true) {
return undefined;
}
var io = irpcObj();
io.input.level = irpc.SMBSRV_INFO_TCONS;
status = irpc.smbsrv_information(io);
if (status.is_ok != true) {
return undefined;
}
/* gather the results into a single array */
var i, count=0, ret = new Object();
for (i=0;i<io.results.length;i++) {
var tcons = io.results[i].info.tcons.tcons;
var j;
for (j=0;j<tcons.length;j++) {
ret[count] = tcons[j];
count++;
}
}
ret.length = count;
return ret;
}
/*
return nbtd statistics
*/
function nbtd_statistics()
{
var irpc = irpc_init();
status = irpc.connect("nbt_server");
if (status.is_ok != true) {
return undefined;
}
var io = irpcObj();
io.input.level = irpc.NBTD_INFO_STATISTICS;
status = irpc.nbtd_information(io);
if (status.is_ok != true) {
return undefined;
}
return io.results[0].info.stats;
}
/*
see if a service is enabled
*/
function service_enabled(name)
{
var lp = loadparm_init();
var services = lp.get("server services");
var i;
for (i=0;i<services.length;i++) {
if (services[i] == name) {
return true;
}
}
return false;
}
/*
show status of a server
*/
function server_status(name)
{
var i;
var io;
var irpc = irpc_init();
if (!service_enabled(name)) {
return "DISABLED";
}
status = irpc.connect(name + "_server");
if (status.is_ok != true) {
return "DOWN";
}
var io = irpcObj();
status = irpc.irpc_uptime(io);
if (status.is_ok != true) {
return "NOT RESPONDING";
}
return "RUNNING";
}
/*
show status of a stream server
*/
function stream_server_status(name)
{
var irpc = irpc_init();
if (!service_enabled(name)) {
return "DISABLED";
}
status = irpc.connect(name + "_server");
if (status.is_ok != true) {
return "0 connections";
}
var io = irpcObj();
status = irpc.irpc_uptime(io);
if (status.is_ok != true) {
return "NOT RESPONDING";
}
var n = io.results.length;
return sprintf("%u connection%s", n, plural(n));
}
+870
View File
@@ -0,0 +1,870 @@
/*
backend code for provisioning a Samba4 server
Copyright Andrew Tridgell 2005
Released under the GNU GPL v2 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.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.BASEDN, 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.BASEDN, ldb.SCOPE_SUBTREE, attrs);
if (res.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[0].dn, unixname);
var ok = ldb.modify(mod);
if (!ok) {
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(ldb)
{
println("Deleting " + ldb.filename);
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(ldb)
{
var res;
/* delete the specials */
ldb.del("@INDEXLIST");
ldb.del("@ATTRIBUTES");
ldb.del("@SUBCLASSES");
ldb.del("@MODULES");
ldb.del("@PARTITION");
ldb.del("@KLUDGEACL");
/* and the rest */
attrs = new Array("dn");
var basedn = "";
var res = ldb.search("(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", basedn, ldb.SCOPE_SUBTREE, attrs);
var i;
if (typeof(res) == "undefined") {
ldb_delete(ldb);
return;
}
for (i=0;i<res.length;i++) {
ldb.del(res[i].dn);
}
var res = ldb.search("(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", basedn, ldb.SCOPE_SUBTREE, attrs);
if (res.length != 0) {
ldb_delete(ldb);
return;
}
assert(res.length == 0);
}
/*
erase an ldb, removing all records
*/
function ldb_erase_partitions(info, ldb)
{
var rootDSE_attrs = new Array("namingContexts");
var lp = loadparm_init();
var j;
var res = ldb.search("(objectClass=*)", "", ldb.SCOPE_BASE, rootDSE_attrs);
assert(typeof(res) != "undefined");
assert(res.length == 1);
if (typeof(res[0].namingContexts) == "undefined") {
return;
}
for (j=0; j<res[0].namingContexts.length; j++) {
var attrs = new Array("dn");
var basedn = res[0].namingContexts[j];
var k;
var previous_remaining = 1;
var current_remaining = 0;
for (k=0; k < 10 && (previous_remaining != current_remaining); k++) {
/* and the rest */
var res2 = ldb.search("(|(objectclass=*)(dn=*))", basedn, ldb.SCOPE_SUBTREE, attrs);
var i;
if (typeof(res2) == "undefined") {
info.message("ldb search failed: " + ldb.errstring() + "\n");
continue;
}
previous_remaining = current_remaining;
current_remaining = res2.length;
for (i=0;i<res2.length;i++) {
ldb.del(res2[i].dn);
}
var res3 = ldb.search("(|(objectclass=*)(dn=*))", basedn, ldb.SCOPE_SUBTREE, attrs);
if (typeof(res3) == "undefined") {
info.message("ldb search failed: " + ldb.errstring() + "\n");
continue;
}
if (res3.length != 0) {
info.message("Failed to delete all records under " + basedn + ", " + res3.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(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_ok = ldb.add(data);
if (!add_ok) {
info.message("ldb load failed: " + ldb.errstring() + "\n");
if (!failok) {
assert(add_ok);
}
}
return add_ok;
}
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_ok = ldb.modify(data);
if (!mod_ok) {
info.message("ldb load failed: " + ldb.errstring() + "\n");
if (!failok) {
assert(mod_ok);
}
}
return mod_ok;
}
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_ok = ldb.modify(data);
if (!mod_ok) {
info.message("ldb load failed: " + ldb.errstring() + "\n");
return mod_ok;
}
return mod_ok;
}
/*
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;
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)
{
var lp = loadparm_init();
var paths = new Object();
paths.smbconf = lp.get("config file");
paths.shareconf = lp.get("private dir") + "/" + "share.ldb";
paths.hklm = "hklm.ldb";
paths.hkcu = "hkcu.ldb";
paths.hkcr = "hkcr.ldb";
paths.hku = "hku.ldb";
paths.hkpd = "hkpd.ldb";
paths.hkpt = "hkpt.ldb";
paths.samdb = lp.get("sam database");
paths.secrets = "secrets.ldb";
paths.dns = lp.get("private dir") + "/" + subobj.DNSDOMAIN + ".zone";
paths.winsdb = "wins.ldb";
paths.ldap_basedn_ldif = lp.get("private dir") + "/" + subobj.DNSDOMAIN + ".ldif";
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.BASEDN, ldb.SCOPE_BASE, attrs);
assert(res.length == 1 && res[0].objectSid != undefined);
var sid = res[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;
}
/*
provision samba4 - caution, this wipes all existing data!
*/
function provision(subobj, message, blank, paths, session_info, credentials)
{
var lp = loadparm_init();
var sys = sys_init();
var info = new Object();
/*
some options need to be upper/lower case
*/
subobj.REALM = strupper(subobj.REALM);
subobj.HOSTNAME = strlower(subobj.HOSTNAME);
subobj.DOMAIN = strupper(subobj.DOMAIN);
assert(valid_netbios_name(subobj.DOMAIN));
subobj.NETBIOSNAME = strupper(subobj.HOSTNAME);
assert(valid_netbios_name(subobj.NETBIOSNAME));
var rdns = split(",", subobj.BASEDN);
subobj.RDN_DC = substr(rdns[0], strlen("DC="));
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) {
message("Setting up smb.conf\n");
setup_file("provision.smb.conf", 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 secrets.ldb\n");
setup_ldb("secrets.ldif", info, paths.secrets);
message("Setting up keytabs\n");
var keytab_ok = credentials_update_all_keytabs();
assert(keytab_ok);
message("Setting up hklm.ldb\n");
setup_ldb("hklm.ldif", info, paths.hklm);
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("Erasing data from partitions\n");
ldb_erase_partitions(info, samdb);
message("Adding baseDN: " + subobj.BASEDN + " (permitted to fail)\n");
var add_ok = setup_add_ldif("provision_basedn.ldif", info, samdb, true);
message("Modifying baseDN: " + subobj.BASEDN + "\n");
var modify_ok = setup_ldb_modify("provision_basedn_modify.ldif", info, samdb);
if (!modify_ok) {
if (!add_ok) {
message("Failed to both add and modify " + subobj.BASEDN + " in target " + subobj.LDAPBACKEND + "\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("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);
// (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 display specifiers\n");
setup_add_ldif("display_specifiers.ldif", info, samdb, false);
message("Setting up sam.ldb templates\n");
setup_add_ldif("provision_templates.ldif", info, samdb, false);
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);
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 (setup_name_mappings(info, samdb) == false) {
return false;
}
message("Setting up sam.ldb index\n");
setup_add_ldif("provision_index.ldif", info, samdb, false);
var commit_ok = samdb.transaction_commit();
if (!commit_ok) {
info.message("samdb commit failed: " + samdb.errstring() + "\n");
assert(commit_ok);
}
return true;
}
/* Write out a DNS zone file, from the info in the current database */
function provision_dns(subobj, message, paths, session_info, credentials)
{
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.BASEDN, ldb.SCOPE_BASE, attrs);
assert(res.length == 1);
assert(res[0].objectGUID != undefined);
subobj.DOMAINGUID = res[0].objectGUID;
subobj.HOSTGUID = searchone(ldb, subobj.BASEDN, "(&(objectClass=computer)(cn=" + subobj.NETBIOSNAME + "))", "objectGUID");
assert(subobj.HOSTGUID != undefined);
setup_file("provision.zone",
message, paths.dns,
subobj);
message("Please install the zone located in " + paths.dns + " into your DNS server\n");
}
/* Write out a DNS zone file, from the info in the current database */
function provision_ldapbase(subobj, message, paths)
{
message("Setting up LDAP base entry: " + subobj.BASEDN + " \n");
var rdns = split(",", subobj.BASEDN);
subobj.EXTENSIBLEOBJECT = "objectClass: extensibleObject";
subobj.RDN_DC = substr(rdns[0], strlen("DC="));
setup_file("provision_basedn.ldif",
message, paths.ldap_basedn_ldif,
subobj);
message("Please install the LDIF located in " + paths.ldap_basedn_ldif + " into your LDAP server, and re-run with --ldap-backend=ldap://my.ldap.server\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.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.INVOCATIONID = randguid();
subobj.KRBTGTPASS = randpass(12);
subobj.MACHINEPASS = randpass(12);
subobj.ADMINPASS = randpass(12);
subobj.DEFAULTSITE = "Default-First-Site-Name";
subobj.NEWGUID = randguid;
subobj.NTTIME = nttime;
subobj.LDAPTIME = ldaptime;
subobj.DATESTRING = datestring;
subobj.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");
subobj.DNSDOMAIN = strlower(subobj.REALM);
subobj.DNSNAME = sprintf("%s.%s",
strlower(subobj.HOSTNAME),
subobj.DNSDOMAIN);
rdn_list = split(".", subobj.DNSDOMAIN);
subobj.BASEDN = "DC=" + join(",DC=", rdn_list);
subobj.LDAPBACKEND = "users.ldb";
subobj.LDAPMODULES = "objectguid";
subobj.EXTENSIBLEOBJECT = "# no objectClass: extensibleObject 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.length != 1 ||
res[0][attribute] == undefined) {
return undefined;
}
return res[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.length == 1);
var userAccountControl = res[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;
}
/*
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.length == 1 && res[0].defaultNamingContext != undefined);
var domain_dn = res[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
memberOf: %s
unixName: %s
sambaPassword: %s
objectClass: user
",
user_dn, username, dom_users,
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 != true) {
message("Failed to add %s - %s\n", user_dn, ldb.errstring());
return false;
}
message("Modifying group %s\n", dom_users);
ok = ldb.modify(modgroup);
if (ok != true) {
message("Failed to modify %s - %s\n", dom_users, ldb.errstring());
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) > 13) 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)) {
message("workgroup '%s' in smb.conf must match chosen domain '%s'\n",
lp.get("workgroup"), subobj.DOMAIN);
return false;
}
if (strupper(lp.get("realm")) != strupper(subobj.REALM)) {
message("realm '%s' in smb.conf must match chosen realm '%s'\n",
lp.get("realm"), subobj.REALM);
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;
+170
View File
@@ -0,0 +1,170 @@
/*
samr rpc utility functions
Copyright Andrew Tridgell 2005
released under the GNU GPL v2 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);
}
}
@@ -0,0 +1,83 @@
/*
server side js functions for handling async calls from js clients
Copyright Andrew Tridgell 2005
released under the GNU GPL Version 2 or later
*/
libinclude("encoder.js");
/*
register a new call
*/
function __register_call(name, func)
{
var c = this;
c.calls[name] = func;
}
/*
run a call sent from the client, and output the returned object (if any)
*/
function __run_call() {
var c = this;
var name = form['ajaj_func'];
if (name == undefined) {
/* no function to run */
return;
}
var args = form['ajaj_args'];
if (args == undefined) {
println("no function arguments given in run_call");
exit(0);
}
args = decodeObject(args);
if (c.calls[name] == undefined) {
println("undefined remote call " + name);
exit(0);
}
var f = c.calls[name];
var res;
/* oh what a hack - should write a varargs ejs helper */
if (args.length == 0) {
res = f();
} else if (args.length == 1) {
res = f(args[0]);
} else if (args.length == 2) {
res = f(args[0], args[1]);
} else if (args.length == 3) {
res = f(args[0], args[1], args[2]);
} else if (args.length == 4) {
res = f(args[0], args[1], args[2], args[3]);
} else if (args.length == 5) {
res = f(args[0], args[1], args[2], args[3], args[4]);
} else if (args.length == 6) {
res = f(args[0], args[1], args[2], args[3], args[4], args[5]);
} else if (args.length == 7) {
res = f(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
} else if (args.length == 8) {
res = f(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
} else {
println("too many arguments for remote call: " + name);
exit(0);
}
var repobj = new Object();
repobj.res = res;
write(encodeObject(repobj));
exit(0);
}
/*
initialise a server call object
*/
function servCallObj()
{
var c = new Object();
c.add = __register_call;
c.run = __run_call;
c.calls = new Object();
return c;
}
+674
View File
@@ -0,0 +1,674 @@
/*
backend code for upgrading from Samba3
Copyright Jelmer Vernooij 2005
Released under the GNU GPL v2 or later
*/
libinclude("base.js");
function regkey_to_dn(name)
{
var dn = "hive=NONE";
var i = 0;
var as = split("/", name);
for (i in as) {
if (i > 0) {
dn = sprintf("key=%s,", as[i]) + dn;
}
}
return dn;
}
/* Where prefix is any of:
* - HKLM
* HKU
* HKCR
* HKPD
* HKPT
*/
function upgrade_registry(regdb,prefix,ldb)
{
assert(regdb != undefined);
var prefix_up = strupper(prefix);
var ldif = new Array();
for (var i in regdb.keys) {
var rk = regdb.keys[i];
var pts = split("/", rk.name);
/* Only handle selected hive */
if (strupper(pts[0]) != prefix_up) {
continue;
}
var keydn = regkey_to_dn(rk.name);
var pts = split("/", rk.name);
/* Convert key name to dn */
ldif[rk.name] = sprintf("
dn: %s
name: %s
", keydn, pts[0]);
for (var j in rk.values) {
var rv = rk.values[j];
ldif[rk.name + " (" + rv.name + ")"] = sprintf("
dn: %s,value=%s
value: %s
type: %d
data:: %s", keydn, rv.name, rv.name, rv.type, ldb.encode(rv.data));
}
}
return ldif;
}
function upgrade_sam_policy(samba3,dn)
{
var ldif = sprintf("
dn: %s
changetype: modify
replace: minPwdLength
minPwdLength: %d
pwdHistoryLength: %d
minPwdAge: %d
maxPwdAge: %d
lockoutDuration: %d
samba3ResetCountMinutes: %d
samba3UserMustLogonToChangePassword: %d
samba3BadLockoutMinutes: %d
samba3DisconnectTime: %d
", dn, samba3.policy.min_password_length,
samba3.policy.password_history, samba3.policy.minimum_password_age,
samba3.policy.maximum_password_age, samba3.policy.lockout_duration,
samba3.policy.reset_count_minutes, samba3.policy.user_must_logon_to_change_password,
samba3.policy.bad_lockout_minutes, samba3.policy.disconnect_time
);
return ldif;
}
function upgrade_sam_account(ldb,acc,domaindn,domainsid)
{
if (acc.nt_username == undefined) {
acc.nt_username = acc.username;
}
if (acc.nt_username == "") {
acc.nt_username = acc.username;
}
if (acc.fullname == undefined) {
var pw = nss.getpwnam(acc.fullname);
acc.fullname = pw.pw_gecos;
}
var pts = split(',', acc.fullname);
acc.fullname = pts[0];
if (acc.fullname == undefined) {
acc.fullname = acc.username;
}
assert(acc.fullname != undefined);
assert(acc.nt_username != undefined);
var ldif = sprintf(
"dn: cn=%s,%s
objectClass: top
objectClass: user
lastLogon: %d
lastLogoff: %d
unixName: %s
sAMAccountName: %s
cn: %s
description: %s
primaryGroupID: %d
badPwdcount: %d
logonCount: %d
samba3Domain: %s
samba3DirDrive: %s
samba3MungedDial: %s
samba3Homedir: %s
samba3LogonScript: %s
samba3ProfilePath: %s
samba3Workstations: %s
samba3KickOffTime: %d
samba3BadPwdTime: %d
samba3PassLastSetTime: %d
samba3PassCanChangeTime: %d
samba3PassMustChangeTime: %d
objectSid: %s-%d
lmPwdHash:: %s
ntPwdHash:: %s
", ldb.dn_escape(acc.fullname), domaindn, acc.logon_time, acc.logoff_time, acc.username, acc.nt_username, acc.nt_username,
acc.acct_desc, acc.group_rid, acc.bad_password_count, acc.logon_count,
acc.domain, acc.dir_drive, acc.munged_dial, acc.homedir, acc.logon_script,
acc.profile_path, acc.workstations, acc.kickoff_time, acc.bad_password_time,
acc.pass_last_set_time, acc.pass_can_change_time, acc.pass_must_change_time, domainsid, acc.user_rid,
ldb.encode(acc.lm_pw), ldb.encode(acc.nt_pw));
return ldif;
}
function upgrade_sam_group(grp,domaindn)
{
var nss = nss_init();
var gr;
if (grp.sid_name_use == 5) { // Well-known group
return undefined;
}
if (grp.nt_name == "Domain Guests" ||
grp.nt_name == "Domain Users" ||
grp.nt_name == "Domain Admins") {
return undefined;
}
if (grp.gid == -1) {
gr = nss.getgrnam(grp.nt_name);
} else {
gr = nss.getgrgid(grp.gid);
}
if (gr == undefined) {
grp.unixname = "UNKNOWN";
} else {
grp.unixname = gr.gr_name;
}
assert(grp.unixname != undefined);
var ldif = sprintf(
"dn: cn=%s,%s
objectClass: top
objectClass: group
description: %s
cn: %s
objectSid: %s
unixName: %s
samba3SidNameUse: %d
", grp.nt_name, domaindn,
grp.comment, grp.nt_name, grp.sid, grp.unixname, grp.sid_name_use);
return ldif;
}
function upgrade_winbind(samba3,domaindn)
{
var ldif = sprintf("
dn: dc=none
userHwm: %d
groupHwm: %d
", samba3.idmap.user_hwm, samba3.idmap.group_hwm);
for (var i in samba3.idmap.mappings) {
var m = samba3.idmap.mappings[i];
ldif = ldif + sprintf("
dn: SID=%s,%s
SID: %s
type: %d
unixID: %d", m.sid, domaindn, m.sid, m.type, m.unix_id);
}
return ldif;
}
*/
function upgrade_wins(samba3)
{
var ldif = "";
var version_id = 0;
for (i in samba3.winsentries) {
var rType;
var rState;
var nType;
var numIPs = 0;
var e = samba3.winsentries[i];
var now = sys.nttime();
var ttl = sys.unix2nttime(e.ttl);
version_id++;
for (var i in e.ips) {
numIPs++;
}
if (e.type == 0x1C) {
rType = 0x2;
} else if (sys.bitAND(e.type, 0x80)) {
if (numIPs > 1) {
rType = 0x2;
} else {
rType = 0x1;
}
} else {
if (numIPs > 1) {
rType = 0x3;
} else {
rType = 0x0;
}
}
if (ttl > now) {
rState = 0x0;/* active */
} else {
rState = 0x1;/* released */
}
nType = (sys.bitAND(e.nb_flags,0x60)>>5);
ldif = ldif + sprintf("
dn: name=%s,type=0x%02X
type: 0x%02X
name: %s
objectClass: winsRecord
recordType: %u
recordState: %u
nodeType: %u
isStatic: 0
expireTime: %s
versionID: %llu
", e.name, e.type, e.type, e.name,
rType, rState, nType,
sys.ldaptime(ttl), version_id);
for (var i in e.ips) {
ldif = ldif + sprintf("address: %s\n", e.ips[i]);
}
}
ldif = ldif + sprintf("
dn: CN=VERSION
objectClass: winsMaxVersion
maxVersion: %llu
", version_id);
return ldif;
}
function upgrade_provision(samba3)
{
var subobj = new Object();
var nss = nss_init();
var lp = loadparm_init();
var rdn_list;
var domainname = samba3.configuration.get("workgroup");
if (domainname == undefined) {
domainname = samba3.secrets.domains[0].name;
println("No domain specified in smb.conf file, assuming '" + domainname + "'");
}
var domsec = samba3.find_domainsecrets(domainname);
var hostsec = samba3.find_domainsecrets(hostname());
var realm = samba3.configuration.get("realm");
if (realm == undefined) {
realm = domainname;
println("No realm specified in smb.conf file, assuming '" + realm + "'");
}
random_init(local);
subobj.REALM = realm;
subobj.DOMAIN = domainname;
subobj.HOSTNAME = hostname();
assert(subobj.REALM);
assert(subobj.DOMAIN);
assert(subobj.HOSTNAME);
subobj.HOSTIP = hostip();
if (domsec != undefined) {
subobj.DOMAINGUID = domsec.guid;
subobj.DOMAINSID = domsec.sid;
} else {
println("Can't find domain secrets for '" + domainname + "'; using random SID and GUID");
subobj.DOMAINGUID = randguid();
subobj.DOMAINSID = randsid();
}
if (hostsec) {
subobj.HOSTGUID = hostsec.guid;
} else {
subobj.HOSTGUID = randguid();
}
subobj.INVOCATIONID = randguid();
subobj.KRBTGTPASS = randpass(12);
subobj.MACHINEPASS = randpass(12);
subobj.ADMINPASS = randpass(12);
subobj.DEFAULTSITE = "Default-First-Site-Name";
subobj.NEWGUID = randguid;
subobj.NTTIME = nttime;
subobj.LDAPTIME = ldaptime;
subobj.DATESTRING = datestring;
subobj.USN = nextusn;
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");
subobj.USERS = findnss(nss.getgrnam, "users", "guest", "other");
subobj.DNSDOMAIN = strlower(subobj.REALM);
subobj.DNSNAME = sprintf("%s.%s",
strlower(subobj.HOSTNAME),
subobj.DNSDOMAIN);
subobj.BASEDN = "DC=" + join(",DC=", split(".", subobj.REALM));
rdn_list = split(".", subobj.REALM);
return subobj;
}
smbconf_keep = new Array(
"dos charset",
"unix charset",
"display charset",
"comment",
"path",
"directory",
"workgroup",
"realm",
"netbios name",
"netbios aliases",
"netbios scope",
"server string",
"interfaces",
"bind interfaces only",
"security",
"auth methods",
"encrypt passwords",
"null passwords",
"obey pam restrictions",
"password server",
"smb passwd file",
"private dir",
"passwd chat",
"password level",
"lanman auth",
"ntlm auth",
"client NTLMv2 auth",
"client lanman auth",
"client plaintext auth",
"read only",
"hosts allow",
"hosts deny",
"log level",
"debuglevel",
"log file",
"smb ports",
"large readwrite",
"max protocol",
"min protocol",
"unicode",
"read raw",
"write raw",
"disable netbios",
"nt status support",
"announce version",
"announce as",
"max mux",
"max xmit",
"name resolve order",
"max wins ttl",
"min wins ttl",
"time server",
"unix extensions",
"use spnego",
"server signing",
"client signing",
"max connections",
"paranoid server security",
"socket options",
"strict sync",
"max print jobs",
"printable",
"print ok",
"printer name",
"printer",
"map system",
"map hidden",
"map archive",
"preferred master",
"prefered master",
"local master",
"browseable",
"browsable",
"wins server",
"wins support",
"csc policy",
"strict locking",
"config file",
"preload",
"auto services",
"lock dir",
"lock directory",
"pid directory",
"socket address",
"copy",
"include",
"available",
"volume",
"fstype",
"panic action",
"msdfs root",
"host msdfs",
"winbind separator");
/*
Remove configuration variables not present in Samba4
oldconf: Old configuration structure
mark: Whether removed configuration variables should be
kept in the new configuration as "samba3:<name>"
*/
function upgrade_smbconf(oldconf,mark)
{
var data = oldconf.data();
var newconf = param_init();
for (var s in data) {
for (var p in data[s]) {
var keep = false;
for (var k in smbconf_keep) {
if (smbconf_keep[k] == p) {
keep = true;
break;
}
}
if (keep) {
newconf.set(s, p, oldconf.get(s, p));
} else if (mark) {
newconf.set(s, "samba3:"+p, oldconf.get(s,p));
}
}
}
if (oldconf.get("domain logons") == "True") {
if (oldconf.get("domain master") == "True") {
newconf.set("server role", "pdc");
} else {
newconf.set("server role", "bdc");
}
} else {
if (oldconf.get("domain master") == "True") {
newconf.set("server role", "standalone");
} else {
newconf.set("server role", "member server");
}
}
return newconf;
}
function upgrade(subobj, samba3, message, paths, session_info, credentials)
{
var ret = 0;
var lp = loadparm_init();
var samdb = ldb_init();
samdb.session_info = session_info;
samdb.credentials = credentials;
var ok = samdb.connect(paths.samdb);
if (!ok) {
info.message("samdb connect failed: " + samdb.errstring() + "\n");
assert(ok);
}
message("Writing configuration\n");
var newconf = upgrade_smbconf(samba3.configuration,true);
newconf.save(paths.smbconf);
message("Importing account policies\n");
var ldif = upgrade_sam_policy(samba3,subobj.BASEDN);
ok = samdb.modify(ldif);
if (!ok) {
message("samdb load failed: " + samdb.errstring() + "\n");
assert(ok);
}
var regdb = ldb_init();
ok = regdb.connect(paths.hklm);
if (!ok) {
message("registry connect: " + regdb.errstring() + "\n");
assert(ok);
}
ok = regdb.modify(sprintf("
dn: value=RefusePasswordChange,key=Parameters,key=Netlogon,key=Services,key=CurrentControlSet,key=System,HIVE=NONE
replace: type
type: 4
replace: data
data: %d
", samba3.policy.refuse_machine_password_change));
if (!ok) {
message("registry load failed: " + regdb.errstring() + "\n");
assert(ok);
}
message("Importing users\n");
for (var i in samba3.samaccounts) {
var msg = "... " + samba3.samaccounts[i].username;
var ldif = upgrade_sam_account(samdb,samba3.samaccounts[i],subobj.BASEDN,subobj.DOMAINSID);
ok = samdb.add(ldif);
if (!ok && samdb.errstring() != "Record exists") {
msg = msg + "... error: " + samdb.errstring();
ret = ret + 1;
}
message(msg + "\n");
}
message("Importing groups\n");
for (var i in samba3.groupmappings) {
var msg = "... " + samba3.groupmappings[i].nt_name;
var ldif = upgrade_sam_group(samba3.groupmappings[i],subobj.BASEDN);
if (ldif != undefined) {
ok = samdb.add(ldif);
if (!ok && samdb.errstring() != "Record exists") {
msg = msg + "... error: " + samdb.errstring();
ret = ret + 1;
}
}
message(msg + "\n");
}
message("Importing registry data\n");
var hives = new Array("hkcr","hkcu","hklm","hkpd","hku","hkpt");
for (var i in hives) {
var hn = hives[i];
message("... " + hn + "\n");
regdb = ldb_init();
ok = regdb.connect(paths[hn]);
assert(ok);
var ldif = upgrade_registry(samba3.registry, hn, regdb);
for (var j in ldif) {
var msg = "... ... " + j;
ok = regdb.add(ldif[j]);
if (!ok && regdb.errstring() != "Record exists") {
msg = msg + "... error: " + regdb.errstring();
ret = ret + 1;
}
message(msg + "\n");
}
}
message("Importing WINS data\n");
var winsdb = ldb_init();
ok = winsdb.connect(paths.winsdb);
assert(ok);
ldb_erase(winsdb);
var ldif = upgrade_wins(samba3);
ok = winsdb.add(ldif);
assert(ok);
// figure out ldapurl, if applicable
var ldapurl = undefined;
var pdb = samba3.configuration.get_list("passdb backend");
if (pdb != undefined) {
for (var b in pdb) {
if (strlen(pdb[b]) >= 7) {
if (substr(pdb[b], 0, 7) == "ldapsam") {
ldapurl = substr(pdb[b], 8);
}
}
}
}
// URL was not specified in passdb backend but ldap /is/ used
if (ldapurl == "") {
ldapurl = "ldap://" + samba3.configuration.get("ldap server");
}
// Enable samba3sam module if original passdb backend was ldap
if (ldapurl != undefined) {
message("Enabling Samba3 LDAP mappings for SAM database\n");
ok = samdb.modify("
dn: @MODULES
changetype: modify
replace: @LIST
@LIST: samldb,operational,objectguid,rdn_name,samba3sam
");
if (!ok) {
message("Error enabling samba3sam module: " + samdb.errstring() + "\n");
ret = ret + 1;
}
ok = samdb.add(sprintf("
dn: @MAP=samba3sam
@MAP_URL: %s", ldapurl));
assert(ok);
}
return ret;
}
function upgrade_verify(subobj, samba3,paths,message)
{
message("Verifying account policies\n");
var samldb = ldb_init();
var ne = 0;
var ok = samldb.connect(paths.samdb);
assert(ok);
for (var i in samba3.samaccounts) {
var msg = samldb.search("(&(sAMAccountName=" + samba3.samaccounts[i].nt_username + ")(objectclass=user))");
assert(msg.length >= 1);
}
// FIXME
}
+291
View File
@@ -0,0 +1,291 @@
/*
winreg rpc utility functions
Copyright Andrew Tridgell 2005
released under the GNU GPL v2 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;
}
+37
View File
@@ -0,0 +1,37 @@
README for Samba SWIG Python extensions
---------------------------------------
Instructions for building:
1. Run configure with the --with-python option to enable python
extensions.
2. Edit the script/build_idl.sh script to pass the --swig option to
pidl. Here's a patch:
Index: script/build_idl.sh
===================================================================
--- script/build_idl.sh (revision 2413)
+++ script/build_idl.sh (working copy)
@@ -4,7 +4,7 @@
[ -d librpc/gen_ndr ] || mkdir -p librpc/gen_ndr || exit 1
-PIDL="$PERL ./build/pidl/pidl.pl --output librpc/gen_ndr/ndr_ --parse --header --parser --server"
+PIDL="$PERL ./build/pidl/pidl.pl --output librpc/gen_ndr/ndr_ --parse --header --parser --server --swig"
TABLES="$PERL ./build/pidl/tables.pl --output librpc/gen_ndr/tables"
if [ x$FULLBUILD = xFULL ]; then
3. Run 'make idl_full swig' to build extensions.
4. At some stage there will be a proper system for installing the
extensions, but right now it's easier to run them in place. Set
your PYTHONPATH to include the modules. From the Samba source
directory, run:
export PYTHONPATH=`pwd`/scripting/swig
Now you can go nuts and use the extensions. Check the
scripting/swig/torture directory for a testsuite. There will
hopefully be a bunch of usage examples somewhere.
+29
View File
@@ -0,0 +1,29 @@
dnl # Scripting subsystem
# Check for python support
PYTHON=
AC_ARG_WITH(python,
[ --with-python=PYTHONNAME build Python libraries],
[ case "${withval-python}" in
yes)
PYTHON=python
;;
no)
PYTHON=
;;
*)
PYTHON=${withval-python}
;;
esac ])
if test x"$PYTHON" != "x"; then
incdir=`python -c 'import sys; print "%s/include/python%d.%d" % (sys.prefix, sys.version_info[[0]], sys.version_info[[1]])'`
CPPFLAGS="$CPPFLAGS -I $incdir"
else
SMB_ENABLE(swig_dcerpc, NO)
fi
AC_SUBST(PYTHON)
+30
View File
@@ -0,0 +1,30 @@
#######################
# Start LIBRARY swig_dcerpc
[LIBRARY::swig_dcerpc]
LIBRARY_REALNAME = _dcerpc.$(SHLIBEXT)
PUBLIC_DEPENDENCIES = LIBCLI_SMB NDR_MISC LIBSAMBA-UTIL LIBSAMBA-CONFIG RPC_NDR_SAMR RPC_NDR_LSA DYNCONFIG
OBJ_FILES = dcerpc_wrap.o
# End LIBRARY swig_dcerpc
#######################
# Swig extensions
swig: lib/tdb/swig/_tdb.$(SHLIBEXT) lib/ldb/swig/_ldb.$(SHLIBEXT) \
libcli/swig/_libcli_nbt.$(SHLIBEXT)
.SUFFIXES: _wrap.c .i
.i_wrap.c:
swig -I$(srcdir)/scripting/swig -python $<
SWIG_INCLUDES = librpc/gen_ndr/samr.i librpc/gen_ndr/lsa.i librpc/gen_ndr/spoolss.i
scripting/swig/dcerpc_wrap.c: scripting/swig/dcerpc.i scripting/swig/samba.i scripting/swig/status_codes.i $(SWIG_INCLUDES)
clean::
@echo "Removing SWIG output files"
@-rm -f scripting/swig/tdb.pyc scripting/swig/tdb.py
# Swig testing
swigtest: swig
./script/tests/test_swig.sh
+239
View File
@@ -0,0 +1,239 @@
/* Tastes like -*- C -*- */
/*
Unix SMB/CIFS implementation.
Swig interface to librpc functions.
Copyright (C) Tim Potter 2004
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
%module dcerpc
%{
/* This symbol is used in both includes.h and Python.h which causes an
annoying compiler warning. */
#ifdef HAVE_FSTAT
#undef HAVE_FSTAT
#endif
#include "includes.h"
#include "dynconfig.h"
#undef strcpy
PyObject *ntstatus_exception, *werror_exception;
/* Set up return of a dcerpc.NTSTATUS exception */
void set_ntstatus_exception(int status)
{
PyObject *obj = Py_BuildValue("(i,s)", status,
nt_errstr(NT_STATUS(status)));
PyErr_SetObject(ntstatus_exception, obj);
}
void set_werror_exception(int status)
{
PyObject *obj = Py_BuildValue("(i,s)", status,
win_errstr(W_ERROR(status)));
PyErr_SetObject(werror_exception, obj);
}
%}
%include "samba.i"
%pythoncode %{
NTSTATUS = _dcerpc.NTSTATUS
WERROR = _dcerpc.WERROR
%}
%init %{
setup_logging("python", DEBUG_STDERR);
lp_load();
ntstatus_exception = PyErr_NewException("_dcerpc.NTSTATUS", NULL, NULL);
werror_exception = PyErr_NewException("_dcerpc.WERROR", NULL, NULL);
PyDict_SetItemString(d, "NTSTATUS", ntstatus_exception);
PyDict_SetItemString(d, "WERROR", werror_exception);
/* BINARY swig_dcerpc INIT */
extern NTSTATUS dcerpc_misc_init(void);
extern NTSTATUS dcerpc_krb5pac_init(void);
extern NTSTATUS dcerpc_samr_init(void);
extern NTSTATUS dcerpc_dcerpc_init(void);
extern NTSTATUS auth_sam_init(void);
extern NTSTATUS dcerpc_lsa_init(void);
extern NTSTATUS dcerpc_netlogon_init(void);
extern NTSTATUS gensec_init(void);
extern NTSTATUS auth_developer_init(void);
extern NTSTATUS gensec_spnego_init(void);
extern NTSTATUS auth_winbind_init(void);
extern NTSTATUS gensec_gssapi_init(void);
extern NTSTATUS gensec_ntlmssp_init(void);
extern NTSTATUS dcerpc_nbt_init(void);
extern NTSTATUS auth_anonymous_init(void);
extern NTSTATUS gensec_krb5_init(void);
extern NTSTATUS dcerpc_schannel_init(void);
extern NTSTATUS dcerpc_epmapper_init(void);
if (NT_STATUS_IS_ERR(dcerpc_misc_init())) exit(1);
if (NT_STATUS_IS_ERR(dcerpc_krb5pac_init())) exit(1);
if (NT_STATUS_IS_ERR(dcerpc_samr_init())) exit(1);
if (NT_STATUS_IS_ERR(dcerpc_dcerpc_init())) exit(1);
if (NT_STATUS_IS_ERR(auth_sam_init())) exit(1);
if (NT_STATUS_IS_ERR(dcerpc_lsa_init())) exit(1);
if (NT_STATUS_IS_ERR(dcerpc_netlogon_init())) exit(1);
if (NT_STATUS_IS_ERR(gensec_init())) exit(1);
if (NT_STATUS_IS_ERR(auth_developer_init())) exit(1);
if (NT_STATUS_IS_ERR(gensec_spnego_init())) exit(1);
if (NT_STATUS_IS_ERR(auth_winbind_init())) exit(1);
if (NT_STATUS_IS_ERR(gensec_gssapi_init())) exit(1);
if (NT_STATUS_IS_ERR(gensec_ntlmssp_init())) exit(1);
if (NT_STATUS_IS_ERR(dcerpc_nbt_init())) exit(1);
if (NT_STATUS_IS_ERR(auth_anonymous_init())) exit(1);
if (NT_STATUS_IS_ERR(gensec_krb5_init())) exit(1);
if (NT_STATUS_IS_ERR(dcerpc_schannel_init())) exit(1);
if (NT_STATUS_IS_ERR(dcerpc_epmapper_init())) exit(1);
%}
%typemap(in, numinputs=0) struct dcerpc_pipe **OUT (struct dcerpc_pipe *temp_dcerpc_pipe) {
$1 = &temp_dcerpc_pipe;
}
%typemap(in, numinputs=0) TALLOC_CTX * {
$1 = talloc_init("$symname");
}
%typemap(freearg) TALLOC_CTX * {
// talloc_free($1);
}
%typemap(argout) struct dcerpc_pipe ** {
long status = PyLong_AsLong(resultobj);
/* Throw exception if result was not OK */
if (status != 0) {
set_ntstatus_exception(status);
return NULL;
}
/* Set REF_ALLOC flag so we don't have to do too much extra
mucking around with ref variables in ndr unmarshalling. */
(*$1)->conn->flags |= DCERPC_NDR_REF_ALLOC;
/* Return swig handle on dcerpc_pipe */
resultobj = SWIG_NewPointerObj(*$1, SWIGTYPE_p_dcerpc_pipe, 0);
}
%types(struct dcerpc_pipe *);
%rename(pipe_connect) dcerpc_pipe_connect;
NTSTATUS dcerpc_pipe_connect(TALLOC_CTX *parent_ctx,
struct dcerpc_pipe **OUT,
const char *binding,
const char *pipe_uuid,
uint32_t pipe_version,
struct cli_credentials *credentials);
%typemap(in) DATA_BLOB * (DATA_BLOB temp_data_blob) {
temp_data_blob.data = PyString_AsString($input);
temp_data_blob.length = PyString_Size($input);
$1 = &temp_data_blob;
}
const char *dcerpc_server_name(struct dcerpc_pipe *p);
char *nt_errstr(NTSTATUS nt_code);
/* Some typemaps for easier access to resume handles. Really this can
also be done using the uint32 carray functions, but it's a bit of a
hassle. TODO: Fix memory leak here. */
%typemap(in) uint32_t *resume_handle {
$1 = malloc(sizeof(*$1));
*$1 = PyLong_AsLong($input);
}
%typemap(out) uint32_t *resume_handle {
$result = PyLong_FromLong(*$1);
}
%typemap(in) struct policy_handle * {
if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,
SWIG_POINTER_EXCEPTION)) == -1)
return NULL;
if ($1 == NULL) {
PyErr_SetString(PyExc_TypeError, "None is not a valid policy handle");
return NULL;
}
}
/* When returning a policy handle to Python we need to make a copy of
as the talloc context it is created under is destroyed after the
wrapper function returns. TODO: Fix memory leak created here. */
%typemap(out) struct policy_handle * {
if ($1) {
struct policy_handle *temp = (struct policy_handle *)malloc(sizeof(struct policy_handle));
memcpy(temp, $1, sizeof(struct policy_handle));
$result = SWIG_NewPointerObj(temp, SWIGTYPE_p_policy_handle, 0);
} else {
Py_INCREF(Py_None);
$result = Py_None;
}
}
%{
#include "librpc/gen_ndr/ndr_misc.h"
#include "librpc/gen_ndr/ndr_security.h"
#include "librpc/gen_ndr/ndr_samr.h"
%}
%include "carrays.i"
/* Some functions for accessing arrays of fixed-width integers. */
%array_functions(uint8_t, uint8_array);
%array_functions(uint16_t, uint16_array);
%array_functions(uint32_t, uint32_array);
/* Functions for handling arrays of structures. It would be nice for
pidl to automatically generating these instead of having to find
them all by hand. */
%array_functions(struct samr_SamEntry, samr_SamEntry_array);
%array_functions(union samr_ConnectInfo, samr_ConnectInfo_array);
%array_functions(struct samr_RidWithAttribute, samr_RidWithAttribute_array);
%array_functions(struct lsa_SidPtr, lsa_SidPtr_array);
%include "librpc/gen_ndr/misc.i"
%include "librpc/gen_ndr/security.i"
%include "librpc/gen_ndr/samr.i"
%include "librpc/gen_ndr/lsa.i"
+301
View File
@@ -0,0 +1,301 @@
#!/usr/bin/python
import sys, os, string
from cmd import Cmd
from optparse import OptionParser
from pprint import pprint
import dcerpc, samr
def swig2dict(obj):
"""Convert a swig object to a dictionary."""
result = {}
for attr in filter(lambda x: type(x) == str, dir(obj)):
if attr[:2] == '__' and attr[-2:] == '__':
continue
if attr == 'this' or attr == 'thisown':
continue
result[attr] = getattr(obj, attr)
return result
class rpcclient(Cmd):
prompt = 'rpcclient$ '
def __init__(self, server, cred):
Cmd.__init__(self)
self.server = server
self.cred = cred
def emptyline(self):
# Default for empty line is to repeat last command - yuck
pass
def onecmd(self, line):
# Override the onecmd() method so we can trap error returns
try:
Cmd.onecmd(self, line)
except dcerpc.NTSTATUS, arg:
print 'The command returned an error: %s' % arg[1]
# Command handlers
def do_help(self, line):
"""Displays on-line help for rpcclient commands."""
Cmd.do_help(self, line)
def do_shell(self, line):
status = os.system(line)
if os.WIFEXITED(status):
if os.WEXITSTATUS(status) != 0:
print 'Command exited with code %d' % os.WEXITSTATUS(status)
else:
print 'Command exited with signal %d' % os.WTERMSIG(status)
def do_EOF(self, line):
"""Exits rpcclient."""
print
sys.exit(0)
# SAMR pipe commands
def do_SamrEnumDomains(self, line):
"""Enumerate domain names."""
usage = 'usage: SamrEnumDomains'
if line != '':
print usage
return
pipe = dcerpc.pipe_connect(
'ncacn_np:%s' % self.server,
dcerpc.DCERPC_SAMR_UUID, int(dcerpc.DCERPC_SAMR_VERSION),
self.cred)
connect_handle = samr.Connect(pipe)
for i in connect_handle.EnumDomains():
print i
def do_SamrLookupDomain(self, line):
"""Return the SID for a domain."""
usage = 'SamrLookupDomain DOMAIN'
parser = OptionParser(usage)
options, args = parser.parse_args(string.split(line))
if len(args) != 1:
print 'usage:', usage
return
pipe = dcerpc.pipe_connect(
'ncacn_np:%s' % self.server,
dcerpc.DCERPC_SAMR_UUID, int(dcerpc.DCERPC_SAMR_VERSION),
self.cred)
connect_handle = samr.Connect(pipe)
print connect_handle.LookupDomain(args[0])
def do_SamrQueryDomInfo(self, line):
"""Return information about a domain designated by its SID."""
usage = 'SamrQueryDomInfo DOMAIN_SID [info_level]'
parser = OptionParser(usage)
options, args = parser.parse_args(string.split(line))
if (len(args) == 0) or (len(args) > 2):
print 'usage:', usage
return
pipe = dcerpc.pipe_connect(
'ncacn_np:%s' % self.server,
dcerpc.DCERPC_SAMR_UUID, int(dcerpc.DCERPC_SAMR_VERSION),
self.cred)
connect_handle = samr.Connect(pipe)
domain_handle = connect_handle.OpenDomain(args[0])
if (len(args) == 2):
result = domain_handle.QueryDomainInfo(int(args[1]))
else:
result = domain_handle.QueryDomainInfo()
pprint(swig2dict(result))
def do_SamrQueryDomInfo2(self, line):
"""Return information about a domain designated by its SID.
(Windows 2000 and >)"""
usage = 'SamrQueryDomInfo2 DOMAIN_SID [info_level] (Windows 2000 and >)'
parser = OptionParser(usage)
options, args = parser.parse_args(string.split(line))
if len(args) == 0 or len(args) > 2:
print 'usage:', usage
return
pipe = dcerpc.pipe_connect(
'ncacn_np:%s' % self.server,
dcerpc.DCERPC_SAMR_UUID, int(dcerpc.DCERPC_SAMR_VERSION),
self.cred)
connect_handle = samr.Connect(pipe)
domain_handle = connect_handle.OpenDomain(args[0])
if (len(args) == 2):
result = domain_handle.QueryDomainInfo2(int(args[1]))
else:
result = domain_handle.QueryDomainInfo2()
pprint(swig2dict(result))
def do_SamrEnumDomainGroups(self, line):
"""Return the list of groups of a domain designated by its SID."""
usage = 'SamrEnumDomainGroups DOMAIN_SID'
parser = OptionParser(usage)
options, args = parser.parse_args(string.split(line))
if len(args) != 1:
print 'usage:', usage
return
pipe = dcerpc.pipe_connect(
'ncacn_np:%s' % self.server,
dcerpc.DCERPC_SAMR_UUID, int(dcerpc.DCERPC_SAMR_VERSION),
self.cred)
connect_handle = samr.Connect(pipe)
domain_handle = connect_handle.OpenDomain(args[0])
result = domain_handle.EnumDomainGroups()
pprint(result)
def do_SamrEnumDomainAliases(self, line):
"""Return the list of aliases (local groups) of a domain designated
by its SID."""
usage = 'SamrEnumDomainAliases DOMAIN_SID'
parser = OptionParser(usage)
options, args = parser.parse_args(string.split(line))
if len(args) != 1:
print 'usage:', usage
return
pipe = dcerpc.pipe_connect(
'ncacn_np:%s' % self.server,
dcerpc.DCERPC_SAMR_UUID, int(dcerpc.DCERPC_SAMR_VERSION),
self.cred)
connect_handle = samr.Connect(pipe)
domain_handle = connect_handle.OpenDomain(args[0])
result = domain_handle.EnumDomainAliases()
pprint(result)
def do_SamrEnumDomainUsers(self, line):
"""Return the list of users of a domain designated by its SID."""
usage = 'SamrEnumDomainUsers DOMAIN_SID [user_account_flags]'
parser = OptionParser(usage)
options, args = parser.parse_args(string.split(line))
if (len(args) == 0) or (len(args) > 2):
print 'usage:', usage
return
pipe = dcerpc.pipe_connect(
'ncacn_np:%s' % self.server,
dcerpc.DCERPC_SAMR_UUID, int(dcerpc.DCERPC_SAMR_VERSION),
self.cred)
connect_handle = samr.Connect(pipe)
domain_handle = connect_handle.OpenDomain(args[0])
if (len(args) == 2):
result = domain_handle.EnumDomainUsers(int(args[1]))
else:
result = domain_handle.EnumDomainUsers()
pprint(result)
if __name__ == '__main__':
# Parse command line
usage = 'rpcclient SERVER [options]'
if len(sys.argv) == 1:
print usage
sys.exit(1)
server = sys.argv[1]
del(sys.argv[1])
parser = OptionParser(usage)
parser.add_option('-U', '--username', action='store', type='string',
help='Use given credentials when connecting',
metavar='DOMAIN\\username%password',
dest='username')
parser.add_option('-c', '--command', action='store', type='string',
help='Execute COMMAND', dest='command')
options, args = parser.parse_args()
# Break --username up into domain, username and password
cred = None
if not options.username:
options.username = '%'
domain = ''
if string.find(options.username, '\\') != -1:
domain, options.username = string.split(options.username, '\\')
password = ''
if string.find(options.username, '%') != -1:
options.username, password = string.split(options.username, '%')
username = options.username
if username != '':
cred = (domain, username, password)
# Run command loop
c = rpcclient(server, cred)
if options.command:
c.onecmd(options.command)
sys.exit(0)
while 1:
try:
c.cmdloop()
except KeyboardInterrupt:
print 'KeyboardInterrupt'
+85
View File
@@ -0,0 +1,85 @@
/*
Unix SMB/CIFS implementation.
Common swig definitions
Copyright (C) 2004 Tim Potter <tpot@samba.org>
** NOTE! The following LGPL license applies to the swig
** definitions. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
%apply int { uint8_t };
%apply int { int8_t };
%apply unsigned int { uint16_t };
%apply int { int16_t };
%apply unsigned long long { uint64_t };
%apply long long { int64_t };
%typemap(in) uint32_t {
if (PyLong_Check($input))
$1 = PyLong_AsUnsignedLong($input);
else if (PyInt_Check($input))
$1 = PyInt_AsLong($input);
else {
PyErr_SetString(PyExc_TypeError,"Expected a long or an int");
return NULL;
}
}
%typemap(out) uint32_t {
$result = PyLong_FromUnsignedLong($1);
}
%typemap(in) NTSTATUS {
if (PyLong_Check($input))
$1 = NT_STATUS(PyLong_AsUnsignedLong($input));
else if (PyInt_Check($input))
$1 = NT_STATUS(PyInt_AsLong($input));
else {
PyErr_SetString(PyExc_TypeError, "Expected a long or an int");
return NULL;
}
}
%typemap(out) NTSTATUS {
$result = PyLong_FromUnsignedLong(NT_STATUS_V($1));
}
%typemap(in) struct cli_credentials * {
$1 = cli_credentials_init(NULL);
cli_credentials_set_conf($1);
if ($input == Py_None) {
cli_credentials_set_anonymous($1);
} else {
if (!PyTuple_Check($input) ||
PyTuple_Size($input) != 3) {
PyErr_SetString(PyExc_TypeError, "Expecting three element tuple");
return NULL;
}
if (!PyString_Check(PyTuple_GetItem($input, 0)) ||
!PyString_Check(PyTuple_GetItem($input, 1)) ||
!PyString_Check(PyTuple_GetItem($input, 2))) {
PyErr_SetString(PyExc_TypeError, "Expecting string elements");
return NULL;
}
cli_credentials_set_domain($1, PyString_AsString(PyTuple_GetItem($input, 0)), CRED_SPECIFIED);
cli_credentials_set_username($1, PyString_AsString(PyTuple_GetItem($input, 1)), CRED_SPECIFIED);
cli_credentials_set_password($1, PyString_AsString(PyTuple_GetItem($input, 2)), CRED_SPECIFIED);
}
}
+753
View File
@@ -0,0 +1,753 @@
import dcerpc
def sid_to_string(sid):
"""Convert a Python dictionary SID to a string SID."""
result = 'S-%d' % sid.sid_rev_num
result = result + '-%u' % \
(dcerpc.uint8_array_getitem(sid.id_auth, 5) +
(dcerpc.uint8_array_getitem(sid.id_auth, 4) << 8) +
(dcerpc.uint8_array_getitem(sid.id_auth, 3) << 16) +
(dcerpc.uint8_array_getitem(sid.id_auth, 2) << 24))
for i in range(0, sid.num_auths):
result = result + '-%u' % \
dcerpc.uint32_array_getitem(sid.sub_auths, i)
return result
def string_to_sid(string):
"""Convert a string SID to a Python dictionary SID. Throws a
ValueError if the SID string was badly formed."""
if string[0] != 'S':
raise ValueError('Bad SID format')
string = string[1:]
import re
match = re.match('-\d+', string)
if not match:
raise ValueError('Bad SID format')
try:
sid_rev_num = int(string[match.start()+1:match.end()])
except ValueError:
raise ValueError('Bad SID format')
string = string[match.end():]
match = re.match('-\d+', string)
if not match:
raise ValueError('Bad SID format')
try:
ia = int(string[match.start()+1:match.end()])
except ValueError:
raise ValueError('Bad SID format')
string = string[match.end():]
id_auth = [0, 0, (ia >> 24) & 0xff, (ia >> 16) & 0xff,
(ia >> 8) & 0xff, ia & 0xff]
num_auths = 0
sub_auths = []
while len(string):
match = re.match('-\d+', string)
if not match:
raise ValueError('Bad SID format')
try:
sa = int(string[match.start() + 1 : match.end()])
except ValueError:
raise ValueError('Bad SID format')
num_auths = num_auths + 1
sub_auths.append(int(sa))
string = string[match.end():]
sid = dcerpc.dom_sid()
sid.sid_rev_num = sid_rev_num
sid.id_auth = dcerpc.new_uint8_array(6)
for i in range(6):
dcerpc.uint8_array_setitem(sid.id_auth, i, id_auth[i])
sid.num_auths = num_auths
sid.sub_auths = dcerpc.new_uint32_array(num_auths)
for i in range(num_auths):
dcerpc.uint32_array_setitem(sid.sub_auths, i, sub_auths[i])
return sid
def call_fn(fn, pipe, args):
"""Wrap up a RPC call and throw an exception is an error was returned."""
result = fn(pipe, args);
if result & 0xc0000000L:
raise dcerpc.NTSTATUS(result, dcerpc.nt_errstr(result));
return result;
class SamrHandle:
def __init__(self, pipe, handle):
self.pipe = pipe
self.handle = handle
def __del__(self):
if self.handle is not None:
self.Close()
def Close(self):
r = dcerpc.samr_Close()
r.data_in.handle = self.handle
call_fn(dcerpc.dcerpc_samr_Close, self.pipe, r)
self.handle = None
def QuerySecurity(self, sec_info = 7):
r = dcerpc.samr_QuerySecurity()
r.data_in.handle = self.handle
r.data_in.sec_info = sec_info
call_fn(dcerpc.dcerpc_samr_QuerySecurity, self.pipe, r)
return r.data_out.sdbuf
def SetSecurity(self, sdbuf, sec_info = 7):
r = dcerpc.samr_SetSecurity()
r.data_in.handle = self.handle
r.data_in.sec_info = sec_info
r.data_in.sdbuf = sdbuf
call_fn(dcerpc.dcerpc_samr_SetSecurity, self.pipe, r)
class ConnectHandle(SamrHandle):
def EnumDomains(self):
r = dcerpc.samr_EnumDomains()
r.data_in.connect_handle = self.handle
r.data_in.resume_handle = 0
r.data_in.buf_size = -1
domains = []
while 1:
call_fn(dcerpc.dcerpc_samr_EnumDomains, self.pipe, r)
for i in range(r.data_out.sam.count):
domains.append(dcerpc.samr_SamEntry_array_getitem(
r.data_out.sam.entries, i).name.string)
# TODO: Handle more entries here
break
return domains
def LookupDomain(self, domain_name):
r = dcerpc.samr_LookupDomain()
r.data_in.connect_handle = self.handle
r.data_in.domain_name = dcerpc.samr_String()
r.data_in.domain_name.string = domain_name
call_fn(dcerpc.dcerpc_samr_LookupDomain, self.pipe, r)
return sid_to_string(r.data_out.sid);
def OpenDomain(self, domain_sid, access_mask = 0x02000000):
r = dcerpc.samr_OpenDomain()
r.data_in.connect_handle = self.handle
r.data_in.access_mask = access_mask
r.data_in.sid = string_to_sid(domain_sid)
call_fn(dcerpc.dcerpc_samr_OpenDomain, self.pipe, r)
return DomainHandle(self.pipe, r.data_out.domain_handle)
def Shutdown(self):
r = dcerpc.samr_Shutdown()
r.data_in.connect_handle = self.handle
call_fn(dcerpc.dcerpc_samr_Shutdown, self.pipe, r)
def GetDomPwInfo(self, domain_name):
r = dcerpc.samr_GetDomPwInfo()
r.data_in.domain_name = dcerpc.samr_String()
r.data_in.domain_name.string = domain_name
call_fn(dcerpc.dcerpc_samr_GetDomPwInfo, self.pipe, r)
return r.data_out.info
def SetBootKeyInformation(self, unknown1, unknown2, unknown3):
r = dcerpc.samr_GetBootKeyInformation()
r.data_in.connect_handle = self.handle
r.data_in.unknown1 = unknown1
r.data_in.unknown2 = unknown2
r.data_in.unknown3 = unknown3
call_fn(dcerpc.dcerpc_samr_SetBootKeyInformation, self.pipe, r)
class DomainHandle(SamrHandle):
def QueryDomainInfo(self, level = 2):
r = dcerpc.samr_QueryDomainInfo()
r.data_in.domain_handle = self.handle
r.data_in.level = level
call_fn(dcerpc.dcerpc_samr_QueryDomainInfo, self.pipe, r)
return getattr(r.data_out.info, 'info%d' % level)
def QueryDomainInfo2(self, level = 2):
r = dcerpc.samr_QueryDomainInfo2()
r.data_in.domain_handle = self.handle
r.data_in.level = level
call_fn(dcerpc.dcerpc_samr_QueryDomainInfo2, self.pipe, r)
return getattr(r.data_out.info, 'info%d' % level)
def SetDomainInfo(self, level, info):
r = dcerpc.samr_SetDomainInfo()
r.data_in.domain_handle = self.handle
r.data_in.level = level
r.data_in.info = dcerpc.samr_DomainInfo()
setattr(r.data_in.info, 'info%d' % level, info)
call_fn(dcerpc.dcerpc_samr_SetDomainInfo, self.pipe, r)
def EnumDomainGroups(self):
r = dcerpc.samr_EnumDomainGroups()
r.data_in.domain_handle = self.handle
r.data_in.resume_handle = 0
r.data_in.max_size = 1000
call_fn(dcerpc.dcerpc_samr_EnumDomainGroups, self.pipe, r)
groups = []
if r.data_out.sam.entries:
for i in range(r.data_out.sam.count):
groups.append(dcerpc.samr_SamEntry_array_getitem(
r.data_out.sam.entries, i).name.string)
return groups
def EnumDomainAliases(self):
r = dcerpc.samr_EnumDomainAliases()
r.data_in.domain_handle = self.handle
r.data_in.resume_handle = 0
# acct_flags in SamrEnumerateAliasesInDomain has probably
# no meaning so use 0xffffffff like W2K
r.data_in.acct_flags = 0xffffffffL
call_fn(dcerpc.dcerpc_samr_EnumDomainAliases, self.pipe, r)
aliases = []
if r.data_out.sam.entries:
for i in range(r.data_out.sam.count):
aliases.append(dcerpc.samr_SamEntry_array_getitem(
r.data_out.sam.entries, i).name.string)
return aliases
def EnumDomainUsers(self, user_account_flags = 16):
r = dcerpc.samr_EnumDomainUsers()
r.data_in.domain_handle = self.handle
r.data_in.resume_handle = 0
r.data_in.acct_flags = user_account_flags
r.data_in.max_size = 1000
call_fn(dcerpc.dcerpc_samr_EnumDomainUsers, self.pipe, r)
users = []
if r.data_out.sam.entries:
for i in range(r.data_out.sam.count):
users.append(dcerpc.samr_SamEntry_array_getitem(
r.data_out.sam.entries, i).name.string)
return users
def CreateUser(self, account_name, access_mask = 0x02000000):
r = dcerpc.samr_CreateUser()
r.data_in.domain_handle = self.handle
r.data_in.account_name = dcerpc.samr_String()
r.data_in.account_name.string = account_name
r.data_in.access_mask = access_mask
call_fn(dcerpc.dcerpc_samr_CreateUser, self.pipe, r)
return (r.data_out.user_handle,
dcerpc.uint32_array_getitem(r.data_out.rid, 0))
def CreateUser2(self, account_name, acct_flags = 0x00000010,
access_mask = 0x02000000):
r = dcerpc.samr_CreateUser2()
r.data_in.domain_handle = self.handle
r.data_in.account_name = dcerpc.samr_String()
r.data_in.account_name.string = account_name
r.data_in.acct_flags = acct_flags
r.data_in.access_mask = access_mask
call_fn(dcerpc.dcerpc_samr_CreateUser2, self.pipe, r)
return (r.data_out.user_handle,
dcerpc.uint32_array_getitem(r.data_out.access_granted, 0),
dcerpc.uint32_array_getitem(r.data_out.rid, 0))
def OpenUser(self, rid, access_mask = 0x02000000):
r = dcerpc.samr_OpenUser()
r.data_in.domain_handle = self.handle
r.data_in.access_mask = access_mask
r.data_in.rid = rid
call_fn(dcerpc.dcerpc_samr_OpenUser, self.pipe, r)
return UserHandle(self.pipe, r.data_out.user_handle)
def OpenGroup(self, rid, access_mask = 0x02000000):
r = dcerpc.samr_OpenGroup()
r.data_in.domain_handle = self.handle
r.data_in.access_mask = access_mask
r.data_in.rid = rid
call_fn(dcerpc.dcerpc_samr_OpenGroup, self.pipe, r)
return GroupHandle(self.pipe, r.data_out.group_handle)
def OpenAlias(self, rid, access_mask = 0x02000000):
r = dcerpc.samr_OpenAlias()
r.data_in.domain_handle = self.handle
r.data_in.access_mask = access_mask
r.data_in.rid = rid
call_fn(dcerpc.dcerpc_samr_OpenAlias, self.pipe, r)
return AliasHandle(self.pipe, r.data_out.alias_handle)
def CreateDomAlias(self, alias_name, access_mask = 0x02000000):
r = dcerpc.samr_CreateDomAlias()
r.data_in.domain_handle = self.handle
r.data_in.alias_name = dcerpc.samr_String()
r.data_in.alias_name.string = alias_name
r.data_in.access_mask = access_mask
call_fn(dcerpc.dcerpc_samr_CreateDomAlias, self.pipe, r)
return (AliasHandle(self.pipe, r.data_out.alias_handle),
r.data_out.rid)
def RidToSid(self, rid):
r = dcerpc.samr_RidToSid()
r.data_in.domain_handle = self.handle
r.data_in.rid = rid
call_fn(dcerpc.dcerpc_samr_RidToSid, self.pipe, r)
return sid_to_string(r.data_out.sid)
def RemoveMemberFromForeignDomain(self, sid):
r = dcerpc.samr_RemoveMemberFromForeignDomain()
r.data_in.domain_handle = self.handle
r.data_in.sid = sid
call_fn(dcerpc.dcerpc_samr_RemoveMemberFromForeignDomain, self.pipe, r)
def LookupNames(self, names):
r = dcerpc.samr_LookupNames()
r.data_in.domain_handle = self.handle
r.data_in.num_names = len(names)
r.data_in.names = dcerpc.new_samr_String_array(len(names))
for i in range(len(names)):
s = dcerpc.samr_String()
s.string = names[i]
dcerpc.samr_String_array_setitem(r.data_in.names, i, s)
call_fn(dcerpc.dcerpc_samr_LookupNames, self.pipe, r)
return ([dcerpc.uint32_array_getitem(r.data_out.rids.ids, i)
for i in range(r.data_out.rids.count)],
[dcerpc.uint32_array_getitem(r.data_out.types.ids, i)
for i in range(r.data_out.types.count)])
def CreateDomainGroup(self, domain_name, access_mask = 0x02000000):
r = dcerpc.samr_CreateDomainGroup()
r.data_in.domain_handle = self.handle
r.data_in.name = dcerpc.samr_String()
r.data_in.name.string = domain_name
r.data_in.access_mask = access_mask
call_fn(dcerpc.dcerpc_samr_CreateDomainGroup, self.pipe, r)
def GetAliasMembership(self, sids):
r = dcerpc.samr_GetAliasMembership()
r.data_in.domain_handle = self.handle
r.data_in.sids = dcerpc.lsa_SidArray()
r.data_in.sids.num_sids = len(sids)
r.data_in.sids.sids = dcerpc.new_lsa_SidPtr_array(len(sids))
for i in range(len(sids)):
s = dcerpc.lsa_SidPtr()
s.sid = string_to_sid(sids[i])
dcerpc.lsa_SidPtr_array_setitem(r.data_in.sids.sids, i, s)
call_fn(dcerpc.dcerpc_samr_GetAliasMembership, self.pipe, r)
return [r.ids[x] for x in range(r.count)]
def QueryDisplayInfo(self, level):
# TODO: Handle more data returns
r = dcerpc.samr_QueryDisplayInfo()
r.data_in.domain_handle = self.handle
r.data_in.level = level
r.data_in.start_idx = 0
r.data_in.max_entries = 1000
r.data_in.buf_size = -1
call_fn(dcerpc.dcerpc_samr_QueryDisplayInfo, self.pipe, r)
# TODO: Return a mapping of the various samr_DispInfo
# structures here.
return getattr(r.data_out.info, 'info%d' % level)
def QueryDisplayInfo2(self, level):
# TODO: Handle more data returns
r = dcerpc.samr_QueryDisplayInfo2()
r.data_in.domain_handle = self.handle
r.data_in.level = level
r.data_in.start_idx = 0
r.data_in.max_entries = 1000
r.data_in.buf_size = -1
call_fn(dcerpc.dcerpc_samr_QueryDisplayInfo2, self.pipe, r)
# TODO: Return a mapping of the various samr_DispInfo
# structures here.
return getattr(r.data_out.info, 'info%d' % level)
def QueryDisplayInfo3(self, level):
# TODO: Handle more data returns
r = dcerpc.samr_QueryDisplayInfo3()
r.data_in.domain_handle = self.handle
r.data_in.level = level
r.data_in.start_idx = 0
r.data_in.max_entries = 1000
r.data_in.buf_size = -1
call_fn(dcerpc.dcerpc_samr_QueryDisplayInfo3, self.pipe, r)
# TODO: Return a mapping of the various samr_DispInfo
# structures here.
return getattr(r.data_out.info, 'info%d' % level)
def GetBootKeyInformation(self):
r = dcerpc.samr_GetBootKeyInformation()
r.data_in.domain_handle = self.handle
call_fn(dcerpc.dcerpc_samr_GetBootKeyInformation, self.pipe, r)
return r.data_out.unknown
def SetBootKeyInformation(self):
r = dcerpc.samr_GetBootKeyInformation()
r.data_in.domain_handle = self.handle
call_fn(dcerpc.dcerpc_samr_GetBootKeyInformation, self.pipe, r)
def TestPrivateFunctionsDomain(self):
r = dcerpc.samr_TestPrivateFunctionsDomain()
r.data_in.domain_handle = self.handle
call_fn(dcerpc.dcerpc_samr_TestPrivateFunctionsDomain, self.pipe, r)
class UserHandle(SamrHandle):
def DeleteUser(self):
r = dcerpc.samr_DeleteUser()
r.data_in.user_handle = self.handle
call_fn(dcerpc.dcerpc_samr_DeleteUser, self.pipe, r)
self.handle = None
def GetUserPwInfo(self):
r = dcerpc.samr_GetUserPwInfo()
r.data_in.user_handle = self.handle
call_fn(dcerpc.dcerpc_samr_GetUserPwInfo, self.pipe, r)
return r.data_out.info
def QueryUserInfo(self, level):
r = dcerpc.samr_QueryUserInfo()
r.data_in.user_handle = self.handle
r.data_in.level = level
call_fn(dcerpc.dcerpc_samr_QueryUserInfo, self.pipe, r)
return r.data_out.info
def QueryUserInfo2(self, level):
r = dcerpc.samr_QueryUserInfo2()
r.data_in.user_handle = self.handle
r.data_in.level = level
call_fn(dcerpc.dcerpc_samr_QueryUserInfo2, self.pipe, r)
return r.data_out.info
def GetGroupsForUser(self):
r = dcerpc.samr_GetGroupsForUser()
r.data_in.user_handle = self.handle
call_fn(dcerpc.dcerpc_samr_GetGroupsForUser, self.pipe, r)
rid_types = [dcerpc.samr_RidType_array_getitem(r.data_out.rids.rid, x)
for x in range(r.data_out.rids.count)]
return [(x.rid, x.type) for x in rid_types]
def TestPrivateFunctionsUser(self):
r = dcerpc.samr_TestPrivateFunctionsUser()
r.data_in.user_handle = self.handle
call_fn(dcerpc.dcerpc_samr_TestPrivateFunctionsUser, self.pipe, r)
class GroupHandle(SamrHandle):
def QueryGroupInfo(self, level):
r = dcerpc.samr_QueryGroupInfo()
r.data_in.group_handle = self.handle
r.data_in.level = level
call_fn(dcerpc.dcerpc_samr_QueryGroupInfo, self.pipe, r)
return r.data_out.info
def SetGroupInfo(self, level, info):
r = dcerpc.samr_SetGroupInfo()
r.data_in.group_handle = self.handle
r.data_in.level = level
r.data_in.info = info
call_fn(dcerpc.dcerpc_samr_SetGroupInfo, self.pipe, r)
def QueryGroupMember(self):
r = dcerpc.samr_QueryGroupMember()
r.data_in.group_handle = self.handle
call_fn(dcerpc.dcerpc_samr_QueryGroupMember, self.pipe, r)
return [(dcerpc.uint32_array_getitem(r.data_out.rids.rids, x),
dcerpc.uint32_array_getitem(r.data_out.rids.unknown, x))
for x in range(r.data_out.rids.count)]
class AliasHandle(SamrHandle):
def DeleteDomAlias(self):
r = dcerpc.samr_DeleteDomAlias()
r.data_in.alias_handle = self.handle
call_fn(dcerpc.dcerpc_samr_DeleteDomAlias, self.pipe, r)
self.handle = None
def QueryAliasInfo(self, level = 1):
r = dcerpc.samr_QueryAliasInfo()
r.data_in.alias_handle = self.handle
r.data_in.level = level
call_fn(dcerpc.dcerpc_samr_QueryAliasInfo, self.pipe, r)
return r.data_out.info
def SetAliasInfo(self, level, info):
r = dcerpc.samr_SetAliasInfo()
r.data_in.alias_handle = self.handle
r.data_in.level = level
r.data_in.info = info
call_fn(dcerpc.dcerpc_samr_SetAliasInfo, self.pipe, r)
def AddAliasMember(self, sid):
r = dcerpc.samr_AddAliasMember()
r.data_in.alias_handle = self.handle
r.data_in.sid = string_to_sid(sid)
call_fn(dcerpc.dcerpc_samr_AddAliasMember, self.pipe, r)
def AddMultipleMembersToAlias(self, sids):
r = dcerpc.samr_AddMultipleMembersToAlias()
r.data_in.alias_handle = self.handle
r.data_in.sids = dcerpc.lsa_SidArray()
r.data_in.sids.num_sids = len(sids)
r.data_in.sids.sids = dcerpc.new_lsa_SidPtr_array(len(sids))
for i in range(len(sids)):
s = dcerpc.lsa_SidPtr()
s.sid = string_to_sid(sids[i])
dcerpc.lsa_SidPtr_array_setitem(r.data_in.sids.sids, i, s)
call_fn(dcerpc.dcerpc_samr_AddMultipleMembersToAlias, self.pipe, r)
def GetMembersInAlias(self):
r = dcerpc.samr_GetMembersInAlias()
r.data_in.alias_handle = self.handle
call_fn(dcerpc.dcerpc_samr_GetMembersInAlias, self.pipe, r)
return [
sid_to_string(
dcerpc.lsa_SidPtr_array_getitem(r.data_out.sids.sids, x).sid)
for x in range(r.data_out.sids.num_sids)]
def Connect(pipe, access_mask = 0x02000000):
r = dcerpc.samr_Connect()
r.data_in.system_name = dcerpc.new_uint16_array(1)
dcerpc.uint16_array_setitem(r.data_in.system_name, 0, ord('\\'))
r.data_in.access_mask = access_mask
call_fn(dcerpc.dcerpc_samr_Connect, pipe, r)
return ConnectHandle(pipe, r.data_out.connect_handle)
def Connect2(pipe, system_name = '', access_mask = 0x02000000):
"""Connect to the SAMR pipe."""
r = dcerpc.samr_Connect2()
r.data_in.system_name = system_name
r.data_in.access_mask = access_mask
call_fn(dcerpc.dcerpc_samr_Connect2, pipe, r)
return ConnectHandle(pipe, r.data_out.connect_handle)
def Connect3(pipe, system_name = '', access_mask = 0x02000000):
r = dcerpc.samr_Connect3()
r.data_in.system_name = system_name
r.data_in.unknown = 0
r.data_in.access_mask = access_mask
call_fn(dcerpc.dcerpc_samr_Connect3, pipe, r)
return ConnectHandle(pipe, r.data_out.connect_handle)
def Connect4(pipe, system_name = '', access_mask = 0x02000000):
r = dcerpc.samr_Connect4()
r.data_in.system_name = system_name
r.data_in.unknown = 0
r.data_in.access_mask = access_mask
call_fn(dcerpc.dcerpc_samr_Connect4, pipe, r)
return ConnectHandle(pipe, r.data_out.connect_handle)
def Connect5(pipe, system_name = '', access_mask = 0x02000000):
r = dcerpc.samr_Connect5()
r.data_in.system_name = system_name
r.data_in.access_mask = access_mask
r.data_in.level = 1
r.data_in.info = dcerpc.new_samr_ConnectInfo_array(1)
r.data_in.info.unknown1 = 0
r.data_in.info.unknown2 = 0
call_fn(dcerpc.dcerpc_samr_Connect5, pipe, r)
return ConnectHandle(pipe, r.data_out.connect_handle)
# AddGroupMember
# DeleteDomainGroup
# DeleteGroupMember
# SetMemberAttributesofGroup
# AddAliasMember
# DeleteAliasMember
# GetMembersinAlias
# SetUserInfo
# ChangePasswordUser
# GetDisplayEnumerationIndex
# RemoveMemberFromForeignDomain
# GetDisplayEnumerationIndex2
# RemoveMultipleMembersFromAlias
# OemChangePasswordUser2
# ChangePasswordUser2
# SetUserInfo2
# ChangePasswordUser3
# SetDsrmPassword
# ValidatePassword
+554
View File
@@ -0,0 +1,554 @@
/* Win32 status codes */
#define STATUS_BUFFER_OVERFLOW 0x80000005
#define STATUS_NO_MORE_FILES 0x80000006
#define NT_STATUS_NO_MORE_ENTRIES 0x8000001a
#define STATUS_MORE_ENTRIES 0x0105
#define STATUS_SOME_UNMAPPED 0x0107
#define ERROR_INVALID_PARAMETER 0x0057
#define ERROR_INSUFFICIENT_BUFFER 0x007a
#define STATUS_NOTIFY_ENUM_DIR 0x010c
#define ERROR_INVALID_DATATYPE 0x070c
/* NT status codes */
#define NT_STATUS_OK 0x00000000
#define NT_STATUS_UNSUCCESSFUL 0xC0000001
#define NT_STATUS_NOT_IMPLEMENTED 0xC0000002
#define NT_STATUS_INVALID_INFO_CLASS 0xC0000003
#define NT_STATUS_INFO_LENGTH_MISMATCH 0xC0000004
#define NT_STATUS_ACCESS_VIOLATION 0xC0000005
#define NT_STATUS_IN_PAGE_ERROR 0xC0000006
#define NT_STATUS_PAGEFILE_QUOTA 0xC0000007
#define NT_STATUS_INVALID_HANDLE 0xC0000008
#define NT_STATUS_BAD_INITIAL_STACK 0xC0000009
#define NT_STATUS_BAD_INITIAL_PC 0xC000000a
#define NT_STATUS_INVALID_CID 0xC000000b
#define NT_STATUS_TIMER_NOT_CANCELED 0xC000000c
#define NT_STATUS_INVALID_PARAMETER 0xC000000d
#define NT_STATUS_NO_SUCH_DEVICE 0xC000000e
#define NT_STATUS_NO_SUCH_FILE 0xC000000f
#define NT_STATUS_INVALID_DEVICE_REQUEST 0xC0000010
#define NT_STATUS_END_OF_FILE 0xC0000011
#define NT_STATUS_WRONG_VOLUME 0xC0000012
#define NT_STATUS_NO_MEDIA_IN_DEVICE 0xC0000013
#define NT_STATUS_UNRECOGNIZED_MEDIA 0xC0000014
#define NT_STATUS_NONEXISTENT_SECTOR 0xC0000015
#define NT_STATUS_MORE_PROCESSING_REQUIRED 0xC0000016
#define NT_STATUS_NO_MEMORY 0xC0000017
#define NT_STATUS_CONFLICTING_ADDRESSES 0xC0000018
#define NT_STATUS_NOT_MAPPED_VIEW 0xC0000019
#define NT_STATUS_UNABLE_TO_FREE_VM 0xC000001a
#define NT_STATUS_UNABLE_TO_DELETE_SECTION 0xC000001b
#define NT_STATUS_INVALID_SYSTEM_SERVICE 0xC000001c
#define NT_STATUS_ILLEGAL_INSTRUCTION 0xC000001d
#define NT_STATUS_INVALID_LOCK_SEQUENCE 0xC000001e
#define NT_STATUS_INVALID_VIEW_SIZE 0xC000001f
#define NT_STATUS_INVALID_FILE_FOR_SECTION 0xC0000020
#define NT_STATUS_ALREADY_COMMITTED 0xC0000021
#define NT_STATUS_ACCESS_DENIED 0xC0000022
#define NT_STATUS_BUFFER_TOO_SMALL 0xC0000023
#define NT_STATUS_OBJECT_TYPE_MISMATCH 0xC0000024
#define NT_STATUS_NONCONTINUABLE_EXCEPTION 0xC0000025
#define NT_STATUS_INVALID_DISPOSITION 0xC0000026
#define NT_STATUS_UNWIND 0xC0000027
#define NT_STATUS_BAD_STACK 0xC0000028
#define NT_STATUS_INVALID_UNWIND_TARGET 0xC0000029
#define NT_STATUS_NOT_LOCKED 0xC000002a
#define NT_STATUS_PARITY_ERROR 0xC000002b
#define NT_STATUS_UNABLE_TO_DECOMMIT_VM 0xC000002c
#define NT_STATUS_NOT_COMMITTED 0xC000002d
#define NT_STATUS_INVALID_PORT_ATTRIBUTES 0xC000002e
#define NT_STATUS_PORT_MESSAGE_TOO_LONG 0xC000002f
#define NT_STATUS_INVALID_PARAMETER_MIX 0xC0000030
#define NT_STATUS_INVALID_QUOTA_LOWER 0xC0000031
#define NT_STATUS_DISK_CORRUPT_ERROR 0xC0000032
#define NT_STATUS_OBJECT_NAME_INVALID 0xC0000033
#define NT_STATUS_OBJECT_NAME_NOT_FOUND 0xC0000034
#define NT_STATUS_OBJECT_NAME_COLLISION 0xC0000035
#define NT_STATUS_HANDLE_NOT_WAITABLE 0xC0000036
#define NT_STATUS_PORT_DISCONNECTED 0xC0000037
#define NT_STATUS_DEVICE_ALREADY_ATTACHED 0xC0000038
#define NT_STATUS_OBJECT_PATH_INVALID 0xC0000039
#define NT_STATUS_OBJECT_PATH_NOT_FOUND 0xC000003a
#define NT_STATUS_OBJECT_PATH_SYNTAX_BAD 0xC000003b
#define NT_STATUS_DATA_OVERRUN 0xC000003c
#define NT_STATUS_DATA_LATE_ERROR 0xC000003d
#define NT_STATUS_DATA_ERROR 0xC000003e
#define NT_STATUS_CRC_ERROR 0xC000003f
#define NT_STATUS_SECTION_TOO_BIG 0xC0000040
#define NT_STATUS_PORT_CONNECTION_REFUSED 0xC0000041
#define NT_STATUS_INVALID_PORT_HANDLE 0xC0000042
#define NT_STATUS_SHARING_VIOLATION 0xC0000043
#define NT_STATUS_QUOTA_EXCEEDED 0xC0000044
#define NT_STATUS_INVALID_PAGE_PROTECTION 0xC0000045
#define NT_STATUS_MUTANT_NOT_OWNED 0xC0000046
#define NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED 0xC0000047
#define NT_STATUS_PORT_ALREADY_SET 0xC0000048
#define NT_STATUS_SECTION_NOT_IMAGE 0xC0000049
#define NT_STATUS_SUSPEND_COUNT_EXCEEDED 0xC000004a
#define NT_STATUS_THREAD_IS_TERMINATING 0xC000004b
#define NT_STATUS_BAD_WORKING_SET_LIMIT 0xC000004c
#define NT_STATUS_INCOMPATIBLE_FILE_MAP 0xC000004d
#define NT_STATUS_SECTION_PROTECTION 0xC000004e
#define NT_STATUS_EAS_NOT_SUPPORTED 0xC000004f
#define NT_STATUS_EA_TOO_LARGE 0xC0000050
#define NT_STATUS_NONEXISTENT_EA_ENTRY 0xC0000051
#define NT_STATUS_NO_EAS_ON_FILE 0xC0000052
#define NT_STATUS_EA_CORRUPT_ERROR 0xC0000053
#define NT_STATUS_FILE_LOCK_CONFLICT 0xC0000054
#define NT_STATUS_LOCK_NOT_GRANTED 0xC0000055
#define NT_STATUS_DELETE_PENDING 0xC0000056
#define NT_STATUS_CTL_FILE_NOT_SUPPORTED 0xC0000057
#define NT_STATUS_UNKNOWN_REVISION 0xC0000058
#define NT_STATUS_REVISION_MISMATCH 0xC0000059
#define NT_STATUS_INVALID_OWNER 0xC000005a
#define NT_STATUS_INVALID_PRIMARY_GROUP 0xC000005b
#define NT_STATUS_NO_IMPERSONATION_TOKEN 0xC000005c
#define NT_STATUS_CANT_DISABLE_MANDATORY 0xC000005d
#define NT_STATUS_NO_LOGON_SERVERS 0xC000005e
#define NT_STATUS_NO_SUCH_LOGON_SESSION 0xC000005f
#define NT_STATUS_NO_SUCH_PRIVILEGE 0xC0000060
#define NT_STATUS_PRIVILEGE_NOT_HELD 0xC0000061
#define NT_STATUS_INVALID_ACCOUNT_NAME 0xC0000062
#define NT_STATUS_USER_EXISTS 0xC0000063
#define NT_STATUS_NO_SUCH_USER 0xC0000064
#define NT_STATUS_GROUP_EXISTS 0xC0000065
#define NT_STATUS_NO_SUCH_GROUP 0xC0000066
#define NT_STATUS_MEMBER_IN_GROUP 0xC0000067
#define NT_STATUS_MEMBER_NOT_IN_GROUP 0xC0000068
#define NT_STATUS_LAST_ADMIN 0xC0000069
#define NT_STATUS_WRONG_PASSWORD 0xC000006a
#define NT_STATUS_ILL_FORMED_PASSWORD 0xC000006b
#define NT_STATUS_PASSWORD_RESTRICTION 0xC000006c
#define NT_STATUS_LOGON_FAILURE 0xC000006d
#define NT_STATUS_ACCOUNT_RESTRICTION 0xC000006e
#define NT_STATUS_INVALID_LOGON_HOURS 0xC000006f
#define NT_STATUS_INVALID_WORKSTATION 0xC0000070
#define NT_STATUS_PASSWORD_EXPIRED 0xC0000071
#define NT_STATUS_ACCOUNT_DISABLED 0xC0000072
#define NT_STATUS_NONE_MAPPED 0xC0000073
#define NT_STATUS_TOO_MANY_LUIDS_REQUESTED 0xC0000074
#define NT_STATUS_LUIDS_EXHAUSTED 0xC0000075
#define NT_STATUS_INVALID_SUB_AUTHORITY 0xC0000076
#define NT_STATUS_INVALID_ACL 0xC0000077
#define NT_STATUS_INVALID_SID 0xC0000078
#define NT_STATUS_INVALID_SECURITY_DESCR 0xC0000079
#define NT_STATUS_PROCEDURE_NOT_FOUND 0xC000007a
#define NT_STATUS_INVALID_IMAGE_FORMAT 0xC000007b
#define NT_STATUS_NO_TOKEN 0xC000007c
#define NT_STATUS_BAD_INHERITANCE_ACL 0xC000007d
#define NT_STATUS_RANGE_NOT_LOCKED 0xC000007e
#define NT_STATUS_DISK_FULL 0xC000007f
#define NT_STATUS_SERVER_DISABLED 0xC0000080
#define NT_STATUS_SERVER_NOT_DISABLED 0xC0000081
#define NT_STATUS_TOO_MANY_GUIDS_REQUESTED 0xC0000082
#define NT_STATUS_GUIDS_EXHAUSTED 0xC0000083
#define NT_STATUS_INVALID_ID_AUTHORITY 0xC0000084
#define NT_STATUS_AGENTS_EXHAUSTED 0xC0000085
#define NT_STATUS_INVALID_VOLUME_LABEL 0xC0000086
#define NT_STATUS_SECTION_NOT_EXTENDED 0xC0000087
#define NT_STATUS_NOT_MAPPED_DATA 0xC0000088
#define NT_STATUS_RESOURCE_DATA_NOT_FOUND 0xC0000089
#define NT_STATUS_RESOURCE_TYPE_NOT_FOUND 0xC000008a
#define NT_STATUS_RESOURCE_NAME_NOT_FOUND 0xC000008b
#define NT_STATUS_ARRAY_BOUNDS_EXCEEDED 0xC000008c
#define NT_STATUS_FLOAT_DENORMAL_OPERAND 0xC000008d
#define NT_STATUS_FLOAT_DIVIDE_BY_ZERO 0xC000008e
#define NT_STATUS_FLOAT_INEXACT_RESULT 0xC000008f
#define NT_STATUS_FLOAT_INVALID_OPERATION 0xC0000090
#define NT_STATUS_FLOAT_OVERFLOW 0xC0000091
#define NT_STATUS_FLOAT_STACK_CHECK 0xC0000092
#define NT_STATUS_FLOAT_UNDERFLOW 0xC0000093
#define NT_STATUS_INTEGER_DIVIDE_BY_ZERO 0xC0000094
#define NT_STATUS_INTEGER_OVERFLOW 0xC0000095
#define NT_STATUS_PRIVILEGED_INSTRUCTION 0xC0000096
#define NT_STATUS_TOO_MANY_PAGING_FILES 0xC0000097
#define NT_STATUS_FILE_INVALID 0xC0000098
#define NT_STATUS_ALLOTTED_SPACE_EXCEEDED 0xC0000099
#define NT_STATUS_INSUFFICIENT_RESOURCES 0xC000009a
#define NT_STATUS_DFS_EXIT_PATH_FOUND 0xC000009b
#define NT_STATUS_DEVICE_DATA_ERROR 0xC000009c
#define NT_STATUS_DEVICE_NOT_CONNECTED 0xC000009d
#define NT_STATUS_DEVICE_POWER_FAILURE 0xC000009e
#define NT_STATUS_FREE_VM_NOT_AT_BASE 0xC000009f
#define NT_STATUS_MEMORY_NOT_ALLOCATED 0xC00000a0
#define NT_STATUS_WORKING_SET_QUOTA 0xC00000a1
#define NT_STATUS_MEDIA_WRITE_PROTECTED 0xC00000a2
#define NT_STATUS_DEVICE_NOT_READY 0xC00000a3
#define NT_STATUS_INVALID_GROUP_ATTRIBUTES 0xC00000a4
#define NT_STATUS_BAD_IMPERSONATION_LEVEL 0xC00000a5
#define NT_STATUS_CANT_OPEN_ANONYMOUS 0xC00000a6
#define NT_STATUS_BAD_VALIDATION_CLASS 0xC00000a7
#define NT_STATUS_BAD_TOKEN_TYPE 0xC00000a8
#define NT_STATUS_BAD_MASTER_BOOT_RECORD 0xC00000a9
#define NT_STATUS_INSTRUCTION_MISALIGNMENT 0xC00000aa
#define NT_STATUS_INSTANCE_NOT_AVAILABLE 0xC00000ab
#define NT_STATUS_PIPE_NOT_AVAILABLE 0xC00000ac
#define NT_STATUS_INVALID_PIPE_STATE 0xC00000ad
#define NT_STATUS_PIPE_BUSY 0xC00000ae
#define NT_STATUS_ILLEGAL_FUNCTION 0xC00000af
#define NT_STATUS_PIPE_DISCONNECTED 0xC00000b0
#define NT_STATUS_PIPE_CLOSING 0xC00000b1
#define NT_STATUS_PIPE_CONNECTED 0xC00000b2
#define NT_STATUS_PIPE_LISTENING 0xC00000b3
#define NT_STATUS_INVALID_READ_MODE 0xC00000b4
#define NT_STATUS_IO_TIMEOUT 0xC00000b5
#define NT_STATUS_FILE_FORCED_CLOSED 0xC00000b6
#define NT_STATUS_PROFILING_NOT_STARTED 0xC00000b7
#define NT_STATUS_PROFILING_NOT_STOPPED 0xC00000b8
#define NT_STATUS_COULD_NOT_INTERPRET 0xC00000b9
#define NT_STATUS_FILE_IS_A_DIRECTORY 0xC00000ba
#define NT_STATUS_NOT_SUPPORTED 0xC00000bb
#define NT_STATUS_REMOTE_NOT_LISTENING 0xC00000bc
#define NT_STATUS_DUPLICATE_NAME 0xC00000bd
#define NT_STATUS_BAD_NETWORK_PATH 0xC00000be
#define NT_STATUS_NETWORK_BUSY 0xC00000bf
#define NT_STATUS_DEVICE_DOES_NOT_EXIST 0xC00000c0
#define NT_STATUS_TOO_MANY_COMMANDS 0xC00000c1
#define NT_STATUS_ADAPTER_HARDWARE_ERROR 0xC00000c2
#define NT_STATUS_INVALID_NETWORK_RESPONSE 0xC00000c3
#define NT_STATUS_UNEXPECTED_NETWORK_ERROR 0xC00000c4
#define NT_STATUS_BAD_REMOTE_ADAPTER 0xC00000c5
#define NT_STATUS_PRINT_QUEUE_FULL 0xC00000c6
#define NT_STATUS_NO_SPOOL_SPACE 0xC00000c7
#define NT_STATUS_PRINT_CANCELLED 0xC00000c8
#define NT_STATUS_NETWORK_NAME_DELETED 0xC00000c9
#define NT_STATUS_NETWORK_ACCESS_DENIED 0xC00000ca
#define NT_STATUS_BAD_DEVICE_TYPE 0xC00000cb
#define NT_STATUS_BAD_NETWORK_NAME 0xC00000cc
#define NT_STATUS_TOO_MANY_NAMES 0xC00000cd
#define NT_STATUS_TOO_MANY_SESSIONS 0xC00000ce
#define NT_STATUS_SHARING_PAUSED 0xC00000cf
#define NT_STATUS_REQUEST_NOT_ACCEPTED 0xC00000d0
#define NT_STATUS_REDIRECTOR_PAUSED 0xC00000d1
#define NT_STATUS_NET_WRITE_FAULT 0xC00000d2
#define NT_STATUS_PROFILING_AT_LIMIT 0xC00000d3
#define NT_STATUS_NOT_SAME_DEVICE 0xC00000d4
#define NT_STATUS_FILE_RENAMED 0xC00000d5
#define NT_STATUS_VIRTUAL_CIRCUIT_CLOSED 0xC00000d6
#define NT_STATUS_NO_SECURITY_ON_OBJECT 0xC00000d7
#define NT_STATUS_CANT_WAIT 0xC00000d8
#define NT_STATUS_PIPE_EMPTY 0xC00000d9
#define NT_STATUS_CANT_ACCESS_DOMAIN_INFO 0xC00000da
#define NT_STATUS_CANT_TERMINATE_SELF 0xC00000db
#define NT_STATUS_INVALID_SERVER_STATE 0xC00000dc
#define NT_STATUS_INVALID_DOMAIN_STATE 0xC00000dd
#define NT_STATUS_INVALID_DOMAIN_ROLE 0xC00000de
#define NT_STATUS_NO_SUCH_DOMAIN 0xC00000df
#define NT_STATUS_DOMAIN_EXISTS 0xC00000e0
#define NT_STATUS_DOMAIN_LIMIT_EXCEEDED 0xC00000e1
#define NT_STATUS_OPLOCK_NOT_GRANTED 0xC00000e2
#define NT_STATUS_INVALID_OPLOCK_PROTOCOL 0xC00000e3
#define NT_STATUS_INTERNAL_DB_CORRUPTION 0xC00000e4
#define NT_STATUS_INTERNAL_ERROR 0xC00000e5
#define NT_STATUS_GENERIC_NOT_MAPPED 0xC00000e6
#define NT_STATUS_BAD_DESCRIPTOR_FORMAT 0xC00000e7
#define NT_STATUS_INVALID_USER_BUFFER 0xC00000e8
#define NT_STATUS_UNEXPECTED_IO_ERROR 0xC00000e9
#define NT_STATUS_UNEXPECTED_MM_CREATE_ERR 0xC00000ea
#define NT_STATUS_UNEXPECTED_MM_MAP_ERROR 0xC00000eb
#define NT_STATUS_UNEXPECTED_MM_EXTEND_ERR 0xC00000ec
#define NT_STATUS_NOT_LOGON_PROCESS 0xC00000ed
#define NT_STATUS_LOGON_SESSION_EXISTS 0xC00000ee
#define NT_STATUS_INVALID_PARAMETER_1 0xC00000ef
#define NT_STATUS_INVALID_PARAMETER_2 0xC00000f0
#define NT_STATUS_INVALID_PARAMETER_3 0xC00000f1
#define NT_STATUS_INVALID_PARAMETER_4 0xC00000f2
#define NT_STATUS_INVALID_PARAMETER_5 0xC00000f3
#define NT_STATUS_INVALID_PARAMETER_6 0xC00000f4
#define NT_STATUS_INVALID_PARAMETER_7 0xC00000f5
#define NT_STATUS_INVALID_PARAMETER_8 0xC00000f6
#define NT_STATUS_INVALID_PARAMETER_9 0xC00000f7
#define NT_STATUS_INVALID_PARAMETER_10 0xC00000f8
#define NT_STATUS_INVALID_PARAMETER_11 0xC00000f9
#define NT_STATUS_INVALID_PARAMETER_12 0xC00000fa
#define NT_STATUS_REDIRECTOR_NOT_STARTED 0xC00000fb
#define NT_STATUS_REDIRECTOR_STARTED 0xC00000fc
#define NT_STATUS_STACK_OVERFLOW 0xC00000fd
#define NT_STATUS_NO_SUCH_PACKAGE 0xC00000fe
#define NT_STATUS_BAD_FUNCTION_TABLE 0xC00000ff
#define NT_STATUS_DIRECTORY_NOT_EMPTY 0xC0000101
#define NT_STATUS_FILE_CORRUPT_ERROR 0xC0000102
#define NT_STATUS_NOT_A_DIRECTORY 0xC0000103
#define NT_STATUS_BAD_LOGON_SESSION_STATE 0xC0000104
#define NT_STATUS_LOGON_SESSION_COLLISION 0xC0000105
#define NT_STATUS_NAME_TOO_LONG 0xC0000106
#define NT_STATUS_FILES_OPEN 0xC0000107
#define NT_STATUS_CONNECTION_IN_USE 0xC0000108
#define NT_STATUS_MESSAGE_NOT_FOUND 0xC0000109
#define NT_STATUS_PROCESS_IS_TERMINATING 0xC000010a
#define NT_STATUS_INVALID_LOGON_TYPE 0xC000010b
#define NT_STATUS_NO_GUID_TRANSLATION 0xC000010c
#define NT_STATUS_CANNOT_IMPERSONATE 0xC000010d
#define NT_STATUS_IMAGE_ALREADY_LOADED 0xC000010e
#define NT_STATUS_ABIOS_NOT_PRESENT 0xC000010f
#define NT_STATUS_ABIOS_LID_NOT_EXIST 0xC0000110
#define NT_STATUS_ABIOS_LID_ALREADY_OWNED 0xC0000111
#define NT_STATUS_ABIOS_NOT_LID_OWNER 0xC0000112
#define NT_STATUS_ABIOS_INVALID_COMMAND 0xC0000113
#define NT_STATUS_ABIOS_INVALID_LID 0xC0000114
#define NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE 0xC0000115
#define NT_STATUS_ABIOS_INVALID_SELECTOR 0xC0000116
#define NT_STATUS_NO_LDT 0xC0000117
#define NT_STATUS_INVALID_LDT_SIZE 0xC0000118
#define NT_STATUS_INVALID_LDT_OFFSET 0xC0000119
#define NT_STATUS_INVALID_LDT_DESCRIPTOR 0xC000011a
#define NT_STATUS_INVALID_IMAGE_NE_FORMAT 0xC000011b
#define NT_STATUS_RXACT_INVALID_STATE 0xC000011c
#define NT_STATUS_RXACT_COMMIT_FAILURE 0xC000011d
#define NT_STATUS_MAPPED_FILE_SIZE_ZERO 0xC000011e
#define NT_STATUS_TOO_MANY_OPENED_FILES 0xC000011f
#define NT_STATUS_CANCELLED 0xC0000120
#define NT_STATUS_CANNOT_DELETE 0xC0000121
#define NT_STATUS_INVALID_COMPUTER_NAME 0xC0000122
#define NT_STATUS_FILE_DELETED 0xC0000123
#define NT_STATUS_SPECIAL_ACCOUNT 0xC0000124
#define NT_STATUS_SPECIAL_GROUP 0xC0000125
#define NT_STATUS_SPECIAL_USER 0xC0000126
#define NT_STATUS_MEMBERS_PRIMARY_GROUP 0xC0000127
#define NT_STATUS_FILE_CLOSED 0xC0000128
#define NT_STATUS_TOO_MANY_THREADS 0xC0000129
#define NT_STATUS_THREAD_NOT_IN_PROCESS 0xC000012a
#define NT_STATUS_TOKEN_ALREADY_IN_USE 0xC000012b
#define NT_STATUS_PAGEFILE_QUOTA_EXCEEDED 0xC000012c
#define NT_STATUS_COMMITMENT_LIMIT 0xC000012d
#define NT_STATUS_INVALID_IMAGE_LE_FORMAT 0xC000012e
#define NT_STATUS_INVALID_IMAGE_NOT_MZ 0xC000012f
#define NT_STATUS_INVALID_IMAGE_PROTECT 0xC0000130
#define NT_STATUS_INVALID_IMAGE_WIN_16 0xC0000131
#define NT_STATUS_LOGON_SERVER_CONFLICT 0xC0000132
#define NT_STATUS_TIME_DIFFERENCE_AT_DC 0xC0000133
#define NT_STATUS_SYNCHRONIZATION_REQUIRED 0xC0000134
#define NT_STATUS_DLL_NOT_FOUND 0xC0000135
#define NT_STATUS_OPEN_FAILED 0xC0000136
#define NT_STATUS_IO_PRIVILEGE_FAILED 0xC0000137
#define NT_STATUS_ORDINAL_NOT_FOUND 0xC0000138
#define NT_STATUS_ENTRYPOINT_NOT_FOUND 0xC0000139
#define NT_STATUS_CONTROL_C_EXIT 0xC000013a
#define NT_STATUS_LOCAL_DISCONNECT 0xC000013b
#define NT_STATUS_REMOTE_DISCONNECT 0xC000013c
#define NT_STATUS_REMOTE_RESOURCES 0xC000013d
#define NT_STATUS_LINK_FAILED 0xC000013e
#define NT_STATUS_LINK_TIMEOUT 0xC000013f
#define NT_STATUS_INVALID_CONNECTION 0xC0000140
#define NT_STATUS_INVALID_ADDRESS 0xC0000141
#define NT_STATUS_DLL_INIT_FAILED 0xC0000142
#define NT_STATUS_MISSING_SYSTEMFILE 0xC0000143
#define NT_STATUS_UNHANDLED_EXCEPTION 0xC0000144
#define NT_STATUS_APP_INIT_FAILURE 0xC0000145
#define NT_STATUS_PAGEFILE_CREATE_FAILED 0xC0000146
#define NT_STATUS_NO_PAGEFILE 0xC0000147
#define NT_STATUS_INVALID_LEVEL 0xC0000148
#define NT_STATUS_WRONG_PASSWORD_CORE 0xC0000149
#define NT_STATUS_ILLEGAL_FLOAT_CONTEXT 0xC000014a
#define NT_STATUS_PIPE_BROKEN 0xC000014b
#define NT_STATUS_REGISTRY_CORRUPT 0xC000014c
#define NT_STATUS_REGISTRY_IO_FAILED 0xC000014d
#define NT_STATUS_NO_EVENT_PAIR 0xC000014e
#define NT_STATUS_UNRECOGNIZED_VOLUME 0xC000014f
#define NT_STATUS_SERIAL_NO_DEVICE_INITED 0xC0000150
#define NT_STATUS_NO_SUCH_ALIAS 0xC0000151
#define NT_STATUS_MEMBER_NOT_IN_ALIAS 0xC0000152
#define NT_STATUS_MEMBER_IN_ALIAS 0xC0000153
#define NT_STATUS_ALIAS_EXISTS 0xC0000154
#define NT_STATUS_LOGON_NOT_GRANTED 0xC0000155
#define NT_STATUS_TOO_MANY_SECRETS 0xC0000156
#define NT_STATUS_SECRET_TOO_LONG 0xC0000157
#define NT_STATUS_INTERNAL_DB_ERROR 0xC0000158
#define NT_STATUS_FULLSCREEN_MODE 0xC0000159
#define NT_STATUS_TOO_MANY_CONTEXT_IDS 0xC000015a
#define NT_STATUS_LOGON_TYPE_NOT_GRANTED 0xC000015b
#define NT_STATUS_NOT_REGISTRY_FILE 0xC000015c
#define NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED 0xC000015d
#define NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR 0xC000015e
#define NT_STATUS_FT_MISSING_MEMBER 0xC000015f
#define NT_STATUS_ILL_FORMED_SERVICE_ENTRY 0xC0000160
#define NT_STATUS_ILLEGAL_CHARACTER 0xC0000161
#define NT_STATUS_UNMAPPABLE_CHARACTER 0xC0000162
#define NT_STATUS_UNDEFINED_CHARACTER 0xC0000163
#define NT_STATUS_FLOPPY_VOLUME 0xC0000164
#define NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND 0xC0000165
#define NT_STATUS_FLOPPY_WRONG_CYLINDER 0xC0000166
#define NT_STATUS_FLOPPY_UNKNOWN_ERROR 0xC0000167
#define NT_STATUS_FLOPPY_BAD_REGISTERS 0xC0000168
#define NT_STATUS_DISK_RECALIBRATE_FAILED 0xC0000169
#define NT_STATUS_DISK_OPERATION_FAILED 0xC000016a
#define NT_STATUS_DISK_RESET_FAILED 0xC000016b
#define NT_STATUS_SHARED_IRQ_BUSY 0xC000016c
#define NT_STATUS_FT_ORPHANING 0xC000016d
#define NT_STATUS_PARTITION_FAILURE 0xC0000172
#define NT_STATUS_INVALID_BLOCK_LENGTH 0xC0000173
#define NT_STATUS_DEVICE_NOT_PARTITIONED 0xC0000174
#define NT_STATUS_UNABLE_TO_LOCK_MEDIA 0xC0000175
#define NT_STATUS_UNABLE_TO_UNLOAD_MEDIA 0xC0000176
#define NT_STATUS_EOM_OVERFLOW 0xC0000177
#define NT_STATUS_NO_MEDIA 0xC0000178
#define NT_STATUS_NO_SUCH_MEMBER 0xC000017a
#define NT_STATUS_INVALID_MEMBER 0xC000017b
#define NT_STATUS_KEY_DELETED 0xC000017c
#define NT_STATUS_NO_LOG_SPACE 0xC000017d
#define NT_STATUS_TOO_MANY_SIDS 0xC000017e
#define NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED 0xC000017f
#define NT_STATUS_KEY_HAS_CHILDREN 0xC0000180
#define NT_STATUS_CHILD_MUST_BE_VOLATILE 0xC0000181
#define NT_STATUS_DEVICE_CONFIGURATION_ERROR 0xC0000182
#define NT_STATUS_DRIVER_INTERNAL_ERROR 0xC0000183
#define NT_STATUS_INVALID_DEVICE_STATE 0xC0000184
#define NT_STATUS_IO_DEVICE_ERROR 0xC0000185
#define NT_STATUS_DEVICE_PROTOCOL_ERROR 0xC0000186
#define NT_STATUS_BACKUP_CONTROLLER 0xC0000187
#define NT_STATUS_LOG_FILE_FULL 0xC0000188
#define NT_STATUS_TOO_LATE 0xC0000189
#define NT_STATUS_NO_TRUST_LSA_SECRET 0xC000018a
#define NT_STATUS_NO_TRUST_SAM_ACCOUNT 0xC000018b
#define NT_STATUS_TRUSTED_DOMAIN_FAILURE 0xC000018c
#define NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE 0xC000018d
#define NT_STATUS_EVENTLOG_FILE_CORRUPT 0xC000018e
#define NT_STATUS_EVENTLOG_CANT_START 0xC000018f
#define NT_STATUS_TRUST_FAILURE 0xC0000190
#define NT_STATUS_MUTANT_LIMIT_EXCEEDED 0xC0000191
#define NT_STATUS_NETLOGON_NOT_STARTED 0xC0000192
#define NT_STATUS_ACCOUNT_EXPIRED 0xC0000193
#define NT_STATUS_POSSIBLE_DEADLOCK 0xC0000194
#define NT_STATUS_NETWORK_CREDENTIAL_CONFLICT 0xC0000195
#define NT_STATUS_REMOTE_SESSION_LIMIT 0xC0000196
#define NT_STATUS_EVENTLOG_FILE_CHANGED 0xC0000197
#define NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT 0xC0000198
#define NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT 0xC0000199
#define NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT 0xC000019a
#define NT_STATUS_DOMAIN_TRUST_INCONSISTENT 0xC000019b
#define NT_STATUS_FS_DRIVER_REQUIRED 0xC000019c
#define NT_STATUS_NO_USER_SESSION_KEY 0xC0000202
#define NT_STATUS_USER_SESSION_DELETED 0xC0000203
#define NT_STATUS_RESOURCE_LANG_NOT_FOUND 0xC0000204
#define NT_STATUS_INSUFF_SERVER_RESOURCES 0xC0000205
#define NT_STATUS_INVALID_BUFFER_SIZE 0xC0000206
#define NT_STATUS_INVALID_ADDRESS_COMPONENT 0xC0000207
#define NT_STATUS_INVALID_ADDRESS_WILDCARD 0xC0000208
#define NT_STATUS_TOO_MANY_ADDRESSES 0xC0000209
#define NT_STATUS_ADDRESS_ALREADY_EXISTS 0xC000020a
#define NT_STATUS_ADDRESS_CLOSED 0xC000020b
#define NT_STATUS_CONNECTION_DISCONNECTED 0xC000020c
#define NT_STATUS_CONNECTION_RESET 0xC000020d
#define NT_STATUS_TOO_MANY_NODES 0xC000020e
#define NT_STATUS_TRANSACTION_ABORTED 0xC000020f
#define NT_STATUS_TRANSACTION_TIMED_OUT 0xC0000210
#define NT_STATUS_TRANSACTION_NO_RELEASE 0xC0000211
#define NT_STATUS_TRANSACTION_NO_MATCH 0xC0000212
#define NT_STATUS_TRANSACTION_RESPONDED 0xC0000213
#define NT_STATUS_TRANSACTION_INVALID_ID 0xC0000214
#define NT_STATUS_TRANSACTION_INVALID_TYPE 0xC0000215
#define NT_STATUS_NOT_SERVER_SESSION 0xC0000216
#define NT_STATUS_NOT_CLIENT_SESSION 0xC0000217
#define NT_STATUS_CANNOT_LOAD_REGISTRY_FILE 0xC0000218
#define NT_STATUS_DEBUG_ATTACH_FAILED 0xC0000219
#define NT_STATUS_SYSTEM_PROCESS_TERMINATED 0xC000021a
#define NT_STATUS_DATA_NOT_ACCEPTED 0xC000021b
#define NT_STATUS_NO_BROWSER_SERVERS_FOUND 0xC000021c
#define NT_STATUS_VDM_HARD_ERROR 0xC000021d
#define NT_STATUS_DRIVER_CANCEL_TIMEOUT 0xC000021e
#define NT_STATUS_REPLY_MESSAGE_MISMATCH 0xC000021f
#define NT_STATUS_MAPPED_ALIGNMENT 0xC0000220
#define NT_STATUS_IMAGE_CHECKSUM_MISMATCH 0xC0000221
#define NT_STATUS_LOST_WRITEBEHIND_DATA 0xC0000222
#define NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID 0xC0000223
#define NT_STATUS_PASSWORD_MUST_CHANGE 0xC0000224
#define NT_STATUS_NOT_FOUND 0xC0000225
#define NT_STATUS_NOT_TINY_STREAM 0xC0000226
#define NT_STATUS_RECOVERY_FAILURE 0xC0000227
#define NT_STATUS_STACK_OVERFLOW_READ 0xC0000228
#define NT_STATUS_FAIL_CHECK 0xC0000229
#define NT_STATUS_DUPLICATE_OBJECTID 0xC000022a
#define NT_STATUS_OBJECTID_EXISTS 0xC000022b
#define NT_STATUS_CONVERT_TO_LARGE 0xC000022c
#define NT_STATUS_RETRY 0xC000022d
#define NT_STATUS_FOUND_OUT_OF_SCOPE 0xC000022e
#define NT_STATUS_ALLOCATE_BUCKET 0xC000022f
#define NT_STATUS_PROPSET_NOT_FOUND 0xC0000230
#define NT_STATUS_MARSHALL_OVERFLOW 0xC0000231
#define NT_STATUS_INVALID_VARIANT 0xC0000232
#define NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND 0xC0000233
#define NT_STATUS_ACCOUNT_LOCKED_OUT 0xC0000234
#define NT_STATUS_HANDLE_NOT_CLOSABLE 0xC0000235
#define NT_STATUS_CONNECTION_REFUSED 0xC0000236
#define NT_STATUS_GRACEFUL_DISCONNECT 0xC0000237
#define NT_STATUS_ADDRESS_ALREADY_ASSOCIATED 0xC0000238
#define NT_STATUS_ADDRESS_NOT_ASSOCIATED 0xC0000239
#define NT_STATUS_CONNECTION_INVALID 0xC000023a
#define NT_STATUS_CONNECTION_ACTIVE 0xC000023b
#define NT_STATUS_NETWORK_UNREACHABLE 0xC000023c
#define NT_STATUS_HOST_UNREACHABLE 0xC000023d
#define NT_STATUS_PROTOCOL_UNREACHABLE 0xC000023e
#define NT_STATUS_PORT_UNREACHABLE 0xC000023f
#define NT_STATUS_REQUEST_ABORTED 0xC0000240
#define NT_STATUS_CONNECTION_ABORTED 0xC0000241
#define NT_STATUS_BAD_COMPRESSION_BUFFER 0xC0000242
#define NT_STATUS_USER_MAPPED_FILE 0xC0000243
#define NT_STATUS_AUDIT_FAILED 0xC0000244
#define NT_STATUS_TIMER_RESOLUTION_NOT_SET 0xC0000245
#define NT_STATUS_CONNECTION_COUNT_LIMIT 0xC0000246
#define NT_STATUS_LOGIN_TIME_RESTRICTION 0xC0000247
#define NT_STATUS_LOGIN_WKSTA_RESTRICTION 0xC0000248
#define NT_STATUS_IMAGE_MP_UP_MISMATCH 0xC0000249
#define NT_STATUS_INSUFFICIENT_LOGON_INFO 0xC0000250
#define NT_STATUS_BAD_DLL_ENTRYPOINT 0xC0000251
#define NT_STATUS_BAD_SERVICE_ENTRYPOINT 0xC0000252
#define NT_STATUS_LPC_REPLY_LOST 0xC0000253
#define NT_STATUS_IP_ADDRESS_CONFLICT1 0xC0000254
#define NT_STATUS_IP_ADDRESS_CONFLICT2 0xC0000255
#define NT_STATUS_REGISTRY_QUOTA_LIMIT 0xC0000256
#define NT_STATUS_PATH_NOT_COVERED 0xC0000257
#define NT_STATUS_NO_CALLBACK_ACTIVE 0xC0000258
#define NT_STATUS_LICENSE_QUOTA_EXCEEDED 0xC0000259
#define NT_STATUS_PWD_TOO_SHORT 0xC000025a
#define NT_STATUS_PWD_TOO_RECENT 0xC000025b
#define NT_STATUS_PWD_HISTORY_CONFLICT 0xC000025c
#define NT_STATUS_PLUGPLAY_NO_DEVICE 0xC000025e
#define NT_STATUS_UNSUPPORTED_COMPRESSION 0xC000025f
#define NT_STATUS_INVALID_HW_PROFILE 0xC0000260
#define NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH 0xC0000261
#define NT_STATUS_DRIVER_ORDINAL_NOT_FOUND 0xC0000262
#define NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND 0xC0000263
#define NT_STATUS_RESOURCE_NOT_OWNED 0xC0000264
#define NT_STATUS_TOO_MANY_LINKS 0xC0000265
#define NT_STATUS_QUOTA_LIST_INCONSISTENT 0xC0000266
#define NT_STATUS_FILE_IS_OFFLINE 0xC0000267
#define NT_STATUS_NOT_A_REPARSE_POINT 0xC0000275
#define NT_STATUS_NO_SUCH_JOB 0xC0000EDE
#define WERR_OK 0
#define WERR_BADFUNC 1
#define WERR_BADFILE 2
#define WERR_ACCESS_DENIED 5
#define WERR_BADFID 6
#define WERR_NOMEM 8
#define WERR_GENERAL_FAILURE 31
#define WERR_NOT_SUPPORTED 50
#define WERR_BAD_NETPATH 53
#define WERR_PRINTQ_FULL 61
#define WERR_NO_SPOOL_SPACE 62
#define WERR_NO_SUCH_SHARE 67
#define WERR_ALREADY_EXISTS 80
#define WERR_BAD_PASSWORD 86
#define WERR_INVALID_PARAM 87
#define WERR_INSUFFICIENT_BUFFER 122
#define WERR_INVALID_NAME 123
#define WERR_UNKNOWN_LEVEL 124
#define WERR_OBJECT_PATH_INVALID 161
#define WERR_NO_MORE_ITEMS 259
#define WERR_MORE_DATA 234
#define WERR_INVALID_OWNER 1307
#define WERR_CAN_NOT_COMPLETE 1003
#define WERR_INVALID_SECURITY_DESCRIPTOR 1338
#define WERR_SERVER_UNAVAILABLE 1722
#define WERR_UNKNOWN_PRINTER_DRIVER 1797
#define WERR_INVALID_ENVIRONMENT 1805
#define WERR_INVALID_FORM_NAME 1902
#define WERR_INVALID_FORM_SIZE 1903
#define WERR_BUF_TOO_SMALL 2123
#define WERR_JOB_NOT_FOUND 2151
#define WERR_DEST_NOT_FOUND 2152
#define WERR_NOT_LOCAL_DOMAIN 2320
#define WERR_STATUS_MORE_ENTRIES 0x0105
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/python
import sys
from optparse import OptionParser
# Parse command line
parser = OptionParser()
parser.add_option("-b", "--binding", action="store", type="string",
dest="binding")
parser.add_option("-d", "--domain", action="store", type="string",
dest="domain")
parser.add_option("-u", "--username", action="store", type="string",
dest="username")
parser.add_option("-p", "--password", action="store", type="string",
dest="password")
(options, args) = parser.parse_args()
if not options.binding:
parser.error('You must supply a binding string')
if not options.username or not options.password or not options.domain:
parser.error('You must supply a domain, username and password')
binding = options.binding
domain = options.domain
username = options.username
password = options.password
if len(args) == 0:
parser.error('You must supply the name of a module to test')
# Import and test
for test in args:
try:
module = __import__('torture_%s' % test)
except ImportError:
print 'No such module "%s"' % test
sys.exit(1)
if not hasattr(module, 'runtests'):
print 'Module "%s" does not have a runtests function' % test
module.runtests(binding, (domain, username, password))
@@ -0,0 +1,437 @@
import sys, string
import dcerpc
def ResizeBufferCall(fn, pipe, r):
r['buffer'] = None
r['buf_size'] = 0
result = fn(pipe, r)
if result['result'] == dcerpc.WERR_INSUFFICIENT_BUFFER or \
result['result'] == dcerpc.WERR_MORE_DATA:
r['buffer'] = result['buf_size'] * '\x00'
r['buf_size'] = result['buf_size']
result = fn(pipe, r)
return result
def test_OpenPrinterEx(pipe, printer):
print 'spoolss_OpenPrinterEx(%s)' % printer
printername = '\\\\%s' % dcerpc.dcerpc_server_name(pipe)
if printer is not None:
printername = printername + '\\%s' % printer
r = {}
r['printername'] = printername
r['datatype'] = None
r['devmode_ctr'] = {}
r['devmode_ctr']['size'] = 0
r['devmode_ctr']['devmode'] = None
r['access_mask'] = 0x02000000
r['level'] = 1
r['userlevel'] = {}
r['userlevel']['level1'] = {}
r['userlevel']['level1']['size'] = 0
r['userlevel']['level1']['client'] = None
r['userlevel']['level1']['user'] = None
r['userlevel']['level1']['build'] = 1381
r['userlevel']['level1']['major'] = 2
r['userlevel']['level1']['minor'] = 0
r['userlevel']['level1']['processor'] = 0
result = dcerpc.spoolss_OpenPrinterEx(pipe, r)
return result['handle']
def test_ClosePrinter(pipe, handle):
r = {}
r['handle'] = handle
dcerpc.spoolss_ClosePrinter(pipe, r)
def test_GetPrinter(pipe, handle):
r = {}
r['handle'] = handle
for level in [0, 1, 2, 3, 4, 5, 6, 7]:
print 'spoolss_GetPrinter(level = %d)' % level
r['level'] = level
r['buffer'] = None
r['buf_size'] = 0
result = ResizeBufferCall(dcerpc.spoolss_GetPrinter, pipe, r)
def test_EnumForms(pipe, handle):
print 'spoolss_EnumForms()'
r = {}
r['handle'] = handle
r['level'] = 1
r['buffer'] = None
r['buf_size'] = 0
result = ResizeBufferCall(dcerpc.spoolss_EnumForms, pipe, r)
forms = dcerpc.unmarshall_spoolss_FormInfo_array(
result['buffer'], r['level'], result['count'])
for form in forms:
r = {}
r['handle'] = handle
r['formname'] = form['info1']['formname']
r['level'] = 1
result = ResizeBufferCall(dcerpc.spoolss_GetForm, pipe, r)
def test_EnumPorts(pipe, handle):
print 'spoolss_EnumPorts()'
for level in [1, 2]:
r = {}
r['handle'] = handle
r['servername'] = None
r['level'] = level
result = ResizeBufferCall(dcerpc.spoolss_EnumPorts, pipe, r)
ports = dcerpc.unmarshall_spoolss_PortInfo_array(
result['buffer'], r['level'], result['count'])
if level == 1:
port_names = map(lambda x: x['info1']['port_name'], ports)
def test_DeleteForm(pipe, handle, formname):
r = {}
r['handle'] = handle
r['formname'] = formname
dcerpc.spoolss_DeleteForm(pipe, r)
def test_GetForm(pipe, handle, formname):
r = {}
r['handle'] = handle
r['formname'] = formname
r['level'] = 1
result = ResizeBufferCall(dcerpc.spoolss_GetForm, pipe, r)
return result['info']['info1']
def test_SetForm(pipe, handle, form):
print 'spoolss_SetForm()'
r = {}
r['handle'] = handle
r['level'] = 1
r['formname'] = form['info1']['formname']
r['info'] = form
dcerpc.spoolss_SetForm(pipe, r)
newform = test_GetForm(pipe, handle, r['formname'])
if form['info1'] != newform:
print 'SetForm: mismatch: %s != %s' % \
(r['info']['info1'], f)
sys.exit(1)
def test_AddForm(pipe, handle):
print 'spoolss_AddForm()'
formname = '__testform__'
r = {}
r['handle'] = handle
r['level'] = 1
r['info'] = {}
r['info']['info1'] = {}
r['info']['info1']['formname'] = formname
r['info']['info1']['flags'] = 0x0002
r['info']['info1']['width'] = 100
r['info']['info1']['length'] = 100
r['info']['info1']['left'] = 0
r['info']['info1']['top'] = 1000
r['info']['info1']['right'] = 2000
r['info']['info1']['bottom'] = 3000
try:
result = dcerpc.spoolss_AddForm(pipe, r)
except dcerpc.WERROR, arg:
if arg[0] == dcerpc.WERR_ALREADY_EXISTS:
test_DeleteForm(pipe, handle, formname)
result = dcerpc.spoolss_AddForm(pipe, r)
f = test_GetForm(pipe, handle, formname)
if r['info']['info1'] != f:
print 'AddForm: mismatch: %s != %s' % \
(r['info']['info1'], f)
sys.exit(1)
r['formname'] = formname
test_SetForm(pipe, handle, r['info'])
test_DeleteForm(pipe, handle, formname)
def test_EnumJobs(pipe, handle):
print 'spoolss_EnumJobs()'
r = {}
r['handle'] = handle
r['firstjob'] = 0
r['numjobs'] = 0xffffffff
r['level'] = 1
result = ResizeBufferCall(dcerpc.spoolss_EnumJobs, pipe, r)
if result['buffer'] is None:
return
jobs = dcerpc.unmarshall_spoolss_JobInfo_array(
result['buffer'], r['level'], result['count'])
for job in jobs:
s = {}
s['handle'] = handle
s['job_id'] = job['info1']['job_id']
s['level'] = 1
result = ResizeBufferCall(dcerpc.spoolss_GetJob, pipe, s)
if result['info'] != job:
print 'EnumJobs: mismatch: %s != %s' % (result['info'], job)
sys.exit(1)
# TODO: AddJob, DeleteJob, ScheduleJob
def test_EnumPrinterData(pipe, handle):
print 'test_EnumPrinterData()'
enum_index = 0
while 1:
r = {}
r['handle'] = handle
r['enum_index'] = enum_index
r['value_offered'] = 0
r['data_size'] = 0
result = dcerpc.spoolss_EnumPrinterData(pipe, r)
r['value_offered'] = result['value_needed']
r['data_size'] = result['data_size']
result = dcerpc.spoolss_EnumPrinterData(pipe, r)
if result['result'] == dcerpc.WERR_NO_MORE_ITEMS:
break
s = {}
s['handle'] = handle
s['value_name'] = result['value_name']
result2 = ResizeBufferCall(dcerpc.spoolss_GetPrinterData, pipe, s)
if result['buffer'][:result2['buf_size']] != result2['buffer']:
print 'EnumPrinterData/GetPrinterData mismatch'
sys.exit(1)
enum_index += 1
def test_SetPrinterDataEx(pipe, handle):
valuename = '__printerdataextest__'
data = '12345'
r = {}
r['handle'] = handle
r['key_name'] = 'DsSpooler'
r['value_name'] = valuename
r['type'] = 3
r['buffer'] = data
r['buf_size'] = len(data)
result = dcerpc.spoolss_SetPrinterDataEx(pipe, r)
def test_EnumPrinterDataEx(pipe, handle):
r = {}
r['handle'] = handle
r['key_name'] = 'DsSpooler'
r['buf_size'] = 0
result = dcerpc.spoolss_EnumPrinterDataEx(pipe, r)
if result['result'] == dcerpc.WERR_MORE_DATA:
r['buf_size'] = result['buf_size']
result = dcerpc.spoolss_EnumPrinterDataEx(pipe, r)
# TODO: test spoolss_GetPrinterDataEx()
def test_SetPrinterData(pipe, handle):
print 'testing spoolss_SetPrinterData()'
valuename = '__printerdatatest__'
data = '12345'
r = {}
r['handle'] = handle
r['value_name'] = valuename
r['type'] = 3 # REG_BINARY
r['buffer'] = data
r['real_len'] = 5
dcerpc.spoolss_SetPrinterData(pipe, r)
s = {}
s['handle'] = handle
s['value_name'] = valuename
result = ResizeBufferCall(dcerpc.spoolss_GetPrinterData, pipe, r)
if result['buffer'] != data:
print 'SetPrinterData: mismatch'
sys.exit(1)
dcerpc.spoolss_DeletePrinterData(pipe, r)
def test_EnumPrinters(pipe):
print 'testing spoolss_EnumPrinters()'
printer_names = None
r = {}
r['flags'] = 0x02
r['server'] = None
for level in [0, 1, 2, 4, 5]:
print 'test_EnumPrinters(level = %d)' % level
r['level'] = level
result = ResizeBufferCall(dcerpc.spoolss_EnumPrinters, pipe, r)
printers = dcerpc.unmarshall_spoolss_PrinterInfo_array(
result['buffer'], r['level'], result['count'])
if level == 2:
for p in printers:
# A nice check is for the specversion in the
# devicemode. This has always been observed to be
# 1025.
if p['info2']['devmode']['specversion'] != 1025:
print 'test_EnumPrinters: specversion != 1025'
sys.exit(1)
r['level'] = 1
result = ResizeBufferCall(dcerpc.spoolss_EnumPrinters, pipe, r)
for printer in dcerpc.unmarshall_spoolss_PrinterInfo_array(
result['buffer'], r['level'], result['count']):
if string.find(printer['info1']['name'], '\\\\') == 0:
print 'Skipping remote printer %s' % printer['info1']['name']
continue
printername = string.split(printer['info1']['name'], ',')[0]
handle = test_OpenPrinterEx(pipe, printername)
test_GetPrinter(pipe, handle)
test_EnumPorts(pipe, handle)
test_EnumForms(pipe, handle)
test_AddForm(pipe, handle)
test_EnumJobs(pipe, handle)
test_EnumPrinterData(pipe, handle)
test_EnumPrinterDataEx(pipe, handle)
test_SetPrinterData(pipe, handle)
# test_SetPrinterDataEx(pipe, handle)
test_ClosePrinter(pipe, handle)
def test_EnumPrinterDrivers(pipe):
print 'test spoolss_EnumPrinterDrivers()'
for level in [1, 2, 3]:
r = {}
r['server'] = None
r['environment'] = None
r['level'] = level
result = ResizeBufferCall(dcerpc.spoolss_EnumPrinterDrivers, pipe, r)
drivers = dcerpc.unmarshall_spoolss_DriverInfo_array(
result['buffer'], r['level'], result['count'])
if level == 1:
driver_names = map(lambda x: x['info1']['driver_name'], drivers)
def test_PrintServer(pipe):
handle = test_OpenPrinterEx(pipe, None)
# EnumForms and AddForm tests return WERR_BADFID here (??)
test_ClosePrinter(pipe, handle)
def runtests(binding, domain, username, password):
print 'Testing SPOOLSS pipe'
pipe = dcerpc.pipe_connect(binding,
dcerpc.DCERPC_SPOOLSS_UUID, dcerpc.DCERPC_SPOOLSS_VERSION,
domain, username, password)
test_EnumPrinters(pipe)
test_EnumPrinterDrivers(pipe)
test_PrintServer(pipe)
+83
View File
@@ -0,0 +1,83 @@
#!/usr/bin/python
#
# A torture test for the Python Ldb bindings. Also a short guide on
# how the API works.
#
from Ldb import *
# Helpers
def t(cond, msg):
"""Test a condition."""
if not cond:
raise RuntimeError('FAILED: %s' % msg)
#
# Torture LdbMessage
#
m = LdbMessage()
# Empty message
t(m.keys() == [], 'empty msg')
t(m.dn == None, 'empty dn')
t(m.sanity_check() == LDB_ERR_INVALID_DN_SYNTAX, 'sanity check')
# Test invalid dn
try:
m.dn = 'invalid dn'
except LdbError, arg:
if arg[0] != LDB_ERR_INVALID_DN_SYNTAX:
raise
else:
t(False, 'LdbError not raised')
# Test valid dn
m.dn = 'name=spotty'
t(m.dn == 'name=spotty', 'specified dn')
t(m.sanity_check() == LDB_SUCCESS, 'sanity check')
# Test some single-valued attributes
m['animal'] = 'dog'
m['name'] = 'spotty'
t(m.keys() == ['animal', 'name'], 'keys() test failed')
t(m.values() == [['dog'], ['spotty']], 'values() test failed')
t(m.items() == [('animal', ['dog']), ('name', ['spotty'])],
'items() test failed')
t(m.sanity_check() == LDB_SUCCESS, 'sanity check')
m['animal'] = 'canine'
t(m['animal'] == ['canine'], 'replace value failed')
# Test a multi-valued attribute
names = ['spotty', 'foot']
m['name'] = names
t(m['name'] == names, 'multi-valued attr failed')
t(m.sanity_check() == LDB_SUCCESS, 'sanity check')
# Test non-string attributes
try:
m['foo'] = 42
except TypeError:
pass
else:
t(False, 'TypeError not raised')
#
# Torture Ldb
#
l = Ldb('foo.ldb')
+221
View File
@@ -0,0 +1,221 @@
#!/usr/bin/python
import sys
import dcerpc, samr
def test_Connect(pipe):
handle = samr.Connect(pipe)
handle = samr.Connect2(pipe)
handle = samr.Connect3(pipe)
handle = samr.Connect4(pipe)
# WIN2K3 only?
try:
handle = samr.Connect5(pipe)
except dcerpc.NTSTATUS, arg:
if arg[0] != 0xc00000d2L: # NT_STATUS_NET_WRITE_FAULT
raise
return handle
def test_UserHandle(user_handle):
# QuerySecurity()/SetSecurity()
user_handle.SetSecurity(user_handle.QuerySecurity())
# GetUserPwInfo()
user_handle.GetUserPwInfo()
# GetUserInfo()
for level in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 20,
21, 23, 24, 25, 26]:
try:
user_handle.QueryUserInfo(level)
user_handle.QueryUserInfo2(level)
except dcerpc.NTSTATUS, arg:
if arg[0] != 0xc0000003L: # NT_STATUS_INVALID_INFO_CLASS
raise
# GetGroupsForUser()
user_handle.GetGroupsForUser()
# TestPrivateFunctionsUser()
try:
user_handle.TestPrivateFunctionsUser()
except dcerpc.NTSTATUS, arg:
if arg[0] != 0xC0000002L:
raise
def test_GroupHandle(group_handle):
# QuerySecurity()/SetSecurity()
group_handle.SetSecurity(group_handle.QuerySecurity())
# QueryGroupInfo()
for level in [1, 2, 3, 4, 5]:
info = group_handle.QueryGroupInfo(level)
# TODO: SetGroupinfo()
# QueryGroupMember()
group_handle.QueryGroupMember()
def test_AliasHandle(alias_handle):
# QuerySecurity()/SetSecurity()
alias_handle.SetSecurity(alias_handle.QuerySecurity())
print alias_handle.GetMembersInAlias()
def test_DomainHandle(name, sid, domain_handle):
print 'testing %s (%s)' % (name, sid)
# QuerySecurity()/SetSecurity()
domain_handle.SetSecurity(domain_handle.QuerySecurity())
# LookupNames(), none mapped
try:
domain_handle.LookupNames(['xxNONAMExx'])
except dcerpc.NTSTATUS, arg:
if arg[0] != 0xc0000073L:
raise dcerpc.NTSTATUS(arg)
# LookupNames(), some mapped
if name != 'Builtin':
domain_handle.LookupNames(['Administrator', 'xxNONAMExx'])
# QueryDomainInfo()/SetDomainInfo()
levels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13]
set_ok = [1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0]
for i in range(len(levels)):
info = domain_handle.QueryDomainInfo(level = levels[i])
try:
domain_handle.SetDomainInfo(levels[i], info)
except dcerpc.NTSTATUS, arg:
if not (arg[0] == 0xc0000003L and not set_ok[i]):
raise
# QueryDomainInfo2()
levels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13]
for i in range(len(levels)):
domain_handle.QueryDomainInfo2(level = levels[i])
# EnumDomainUsers
print 'testing users'
users = domain_handle.EnumDomainUsers()
rids = domain_handle.LookupNames(users)
for i in range(len(users)):
test_UserHandle(domain_handle.OpenUser(rids[0][i]))
# QueryDisplayInfo
for i in [1, 2, 3, 4, 5]:
domain_handle.QueryDisplayInfo(level = i)
domain_handle.QueryDisplayInfo2(level = i)
domain_handle.QueryDisplayInfo3(level = i)
# EnumDomainGroups
print 'testing groups'
groups = domain_handle.EnumDomainGroups()
rids = domain_handle.LookupNames(groups)
for i in range(len(groups)):
test_GroupHandle(domain_handle.OpenGroup(rids[0][i]))
# EnumDomainAliases
print 'testing aliases'
aliases = domain_handle.EnumDomainAliases()
rids = domain_handle.LookupNames(aliases)
for i in range(len(aliases)):
test_AliasHandle(domain_handle.OpenAlias(rids[0][i]))
# CreateUser
# CreateUser2
# CreateDomAlias
# RidToSid
# RemoveMemberFromForeignDomain
# CreateDomainGroup
# GetAliasMembership
# GetBootKeyInformation()
try:
domain_handle.GetBootKeyInformation()
except dcerpc.NTSTATUS, arg:
pass
# TestPrivateFunctionsDomain()
try:
domain_handle.TestPrivateFunctionsDomain()
except dcerpc.NTSTATUS, arg:
if arg[0] != 0xC0000002L:
raise
def test_ConnectHandle(connect_handle):
print 'testing connect handle'
# QuerySecurity/SetSecurity
connect_handle.SetSecurity(connect_handle.QuerySecurity())
# Lookup bogus domain
try:
connect_handle.LookupDomain('xxNODOMAINxx')
except dcerpc.NTSTATUS, arg:
if arg[0] != 0xC00000DFL: # NT_STATUS_NO_SUCH_DOMAIN
raise
# Test all domains
for domain_name in connect_handle.EnumDomains():
connect_handle.GetDomPwInfo(domain_name)
sid = connect_handle.LookupDomain(domain_name)
domain_handle = connect_handle.OpenDomain(sid)
test_DomainHandle(domain_name, sid, domain_handle)
# TODO: Test Shutdown() function
def runtests(binding, creds):
print 'Testing SAMR pipe'
pipe = dcerpc.pipe_connect(binding,
dcerpc.DCERPC_SAMR_UUID, int(dcerpc.DCERPC_SAMR_VERSION), creds)
handle = test_Connect(pipe)
test_ConnectHandle(handle)
+90
View File
@@ -0,0 +1,90 @@
#!/usr/bin/python
import sys, os
import Tdb
def fail(msg):
print 'FAILED:', msg
sys.exit(1)
tdb_file = '/tmp/torture_tdb.tdb'
# Create temporary tdb file
t = Tdb.Tdb(tdb_file, flags = Tdb.CLEAR_IF_FIRST)
# Check non-existent key throws KeyError exception
try:
t['__none__']
except KeyError:
pass
else:
fail('non-existent key did not throw KeyError')
# Check storing key
t['bar'] = '1234'
if t['bar'] != '1234':
fail('store key failed')
# Check key exists
if not t.has_key('bar'):
fail('has_key() failed for existing key')
if t.has_key('__none__'):
fail('has_key() succeeded for non-existent key')
# Delete key
try:
del(t['__none__'])
except KeyError:
pass
else:
fail('delete of non-existent key did not throw KeyError')
del t['bar']
if t.has_key('bar'):
fail('delete of existing key did not delete key')
# Clear all keys
t.clear()
if len(t) != 0:
fail('clear failed to remove all keys')
# Other dict functions
t['a'] = '1'
t['ab'] = '12'
t['abc'] = '123'
if len(t) != 3:
fail('len method produced wrong value')
keys = t.keys()
values = t.values()
items = t.items()
if set(keys) != set(['a', 'ab', 'abc']):
fail('keys method produced wrong values')
if set(values) != set(['1', '12', '123']):
fail('values method produced wrong values')
if set(items) != set([('a', '1'), ('ab', '12'), ('abc', '123')]):
fail('values method produced wrong values')
t.close()
# Re-open read-only
t = Tdb.Tdb(tdb_file, open_flags = os.O_RDONLY)
t.keys()
t.close()
# Clean up
os.unlink(tdb_file)
+165
View File
@@ -0,0 +1,165 @@
#!/usr/bin/python
import sys, dcerpc
def test_OpenHKLM(pipe):
r = {}
r['unknown'] = {}
r['unknown']['unknown0'] = 0x9038
r['unknown']['unknown1'] = 0x0000
r['access_required'] = 0x02000000
result = dcerpc.winreg_OpenHKLM(pipe, r)
return result['handle']
def test_QueryInfoKey(pipe, handle):
r = {}
r['handle'] = handle
r['class'] = {}
r['class']['name'] = None
return dcerpc.winreg_QueryInfoKey(pipe, r)
def test_CloseKey(pipe, handle):
r = {}
r['handle'] = handle
dcerpc.winreg_CloseKey(pipe, r)
def test_FlushKey(pipe, handle):
r = {}
r['handle'] = handle
dcerpc.winreg_FlushKey(pipe, r)
def test_GetVersion(pipe, handle):
r = {}
r['handle'] = handle
dcerpc.winreg_GetVersion(pipe, r)
def test_GetKeySecurity(pipe, handle):
r = {}
r['handle'] = handle
r['unknown'] = 4
r['size'] = None
r['data'] = {}
r['data']['max_len'] = 0
r['data']['data'] = ''
result = dcerpc.winreg_GetKeySecurity(pipe, r)
print result
if result['result'] == dcerpc.WERR_INSUFFICIENT_BUFFER:
r['size'] = {}
r['size']['max_len'] = result['data']['max_len']
r['size']['offset'] = 0
r['size']['len'] = result['data']['max_len']
result = dcerpc.winreg_GetKeySecurity(pipe, r)
print result
sys.exit(1)
def test_Key(pipe, handle, name, depth = 0):
# Don't descend too far. Registries can be very deep.
if depth > 2:
return
try:
keyinfo = test_QueryInfoKey(pipe, handle)
except dcerpc.WERROR, arg:
if arg[0] == dcerpc.WERR_ACCESS_DENIED:
return
test_GetVersion(pipe, handle)
test_FlushKey(pipe, handle)
test_GetKeySecurity(pipe, handle)
# Enumerate values in this key
r = {}
r['handle'] = handle
r['name_in'] = {}
r['name_in']['len'] = 0
r['name_in']['max_len'] = (keyinfo['max_valnamelen'] + 1) * 2
r['name_in']['buffer'] = {}
r['name_in']['buffer']['max_len'] = keyinfo['max_valnamelen'] + 1
r['name_in']['buffer']['offset'] = 0
r['name_in']['buffer']['len'] = 0
r['type'] = 0
r['value_in'] = {}
r['value_in']['max_len'] = keyinfo['max_valbufsize']
r['value_in']['offset'] = 0
r['value_in']['len'] = 0
r['value_len1'] = keyinfo['max_valbufsize']
r['value_len2'] = 0
for i in range(0, keyinfo['num_values']):
r['enum_index'] = i
dcerpc.winreg_EnumValue(pipe, r)
# Recursively test subkeys of this key
r = {}
r['handle'] = handle
r['key_name_len'] = 0
r['unknown'] = 0x0414
r['in_name'] = {}
r['in_name']['unknown'] = 0x20a
r['in_name']['key_name'] = {}
r['in_name']['key_name']['name'] = None
r['class'] = {}
r['class']['name'] = None
r['last_changed_time'] = {}
r['last_changed_time']['low'] = 0
r['last_changed_time']['high'] = 0
for i in range(0, keyinfo['num_subkeys']):
r['enum_index'] = i
subkey = dcerpc.winreg_EnumKey(pipe, r)
s = {}
s['handle'] = handle
s['keyname'] = {}
s['keyname']['name'] = subkey['out_name']['name']
s['unknown'] = 0
s['access_mask'] = 0x02000000
result = dcerpc.winreg_OpenKey(pipe, s)
test_Key(pipe, result['handle'], name + '/' + s['keyname']['name'],
depth + 1)
test_CloseKey(pipe, result['handle'])
# Enumerate values
def runtests(binding, domain, username, password):
print 'Testing WINREG pipe'
pipe = dcerpc.pipe_connect(binding,
dcerpc.DCERPC_WINREG_UUID, dcerpc.DCERPC_WINREG_VERSION,
domain, username, password)
handle = test_OpenHKLM(pipe)
test_Key(pipe, handle, 'HKLM')