wmi-1.3.16 from opsview.com
This commit is contained in:
@@ -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
|
||||
#######################
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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(¤t);
|
||||
return mprCreateUndefinedVar();
|
||||
}
|
||||
|
||||
if(this->pos - start_offset == 4) {
|
||||
mprDestroyVar(¤t);
|
||||
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(¤t);
|
||||
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(¤t);
|
||||
return mprCreateUndefinedVar();
|
||||
}
|
||||
mprDestroyVar(¤t);
|
||||
mprCopyVar(¤t, &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(¤t,
|
||||
"length",
|
||||
NULL));
|
||||
mprItoa(oldlen, idx, sizeof(idx));
|
||||
mprSetVar(¤t, 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(¤t, "year", obj);
|
||||
break;
|
||||
case date_field_month:
|
||||
mprSetVar(¤t, "month", obj);
|
||||
break;
|
||||
case date_field_day:
|
||||
mprSetVar(¤t, "day", obj);
|
||||
break;
|
||||
case date_field_hour:
|
||||
mprSetVar(¤t, "hour", obj);
|
||||
break;
|
||||
case date_field_minute:
|
||||
mprSetVar(¤t, "minute", obj);
|
||||
break;
|
||||
case date_field_second:
|
||||
mprSetVar(¤t, "second", obj);
|
||||
break;
|
||||
case date_field_millisecond:
|
||||
mprSetVar(¤t, "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(¤t);
|
||||
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(¤t);
|
||||
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(¤t);
|
||||
return mprCreateUndefinedVar();
|
||||
}
|
||||
break;
|
||||
|
||||
case json_tokener_state_object_value:
|
||||
obj = json_tokener_do_parse(this, &err);
|
||||
if (err != json_tokener_success) {
|
||||
goto out;
|
||||
}
|
||||
mprSetVar(¤t, 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(¤t);
|
||||
*err_p = err;
|
||||
return mprCreateUndefinedVar();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void smb_setup_ejs_literal(void)
|
||||
{
|
||||
ejsDefineStringCFunction(-1,
|
||||
"literal_to_var",
|
||||
literal_to_var,
|
||||
NULL,
|
||||
MPR_VAR_SCRIPT_HANDLE);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user