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
+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;
}