mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
r7072: moved the esp hooks calls to the ejs level, so we can call them from
both esp scripts and ejs scripts. This allows the smbscript program to call all the existing extension calls like lpGet() and ldbSearch() Also fixed smbscript to load smb.conf, and setup logging for DEBUG() I left the unixAuth() routine in web_server/calls.c at the moment, as that is really only useful for esp scripts. I imagine that as we extend esp/ejs, we will put some functions in scripting/ejs/ for use in both ejs and esp, and some functions in web_server/ where they will only be accessed by esp web scripts
This commit is contained in:
parent
a58531dcf3
commit
e59ae64f60
@ -1,9 +1,19 @@
|
||||
#######################
|
||||
# Start LIBRARY SMBCALLS
|
||||
[SUBSYSTEM::SMBCALLS]
|
||||
OBJ_FILES = \
|
||||
scripting/ejs/smbcalls.o \
|
||||
scripting/ejs/mprutil.o
|
||||
REQUIRED_SUBSYSTEMS = EJS LIBBASIC
|
||||
# End SUBSYSTEM SMBCALLS
|
||||
#######################
|
||||
|
||||
#######################
|
||||
# Start BINARY SMBSCRIPT
|
||||
[BINARY::smbscript]
|
||||
OBJ_FILES = \
|
||||
scripting/ejs/smbscript.o
|
||||
REQUIRED_SUBSYSTEMS = EJS LIBBASIC
|
||||
REQUIRED_SUBSYSTEMS = EJS LIBBASIC SMBCALLS
|
||||
# End BINARY SMBSCRIPT
|
||||
#######################
|
||||
|
||||
|
159
source/scripting/ejs/mprutil.c
Normal file
159
source/scripting/ejs/mprutil.c
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
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/ejs/ejs.h"
|
||||
#include "lib/ldb/include/ldb.h"
|
||||
|
||||
/*
|
||||
add an indexed array element to a property
|
||||
*/
|
||||
static void mprAddArray(struct MprVar *var, int i, struct MprVar v)
|
||||
{
|
||||
char idx[16];
|
||||
mprItoa(i, idx, sizeof(idx));
|
||||
mprCreateProperty(var, idx, &v);
|
||||
}
|
||||
|
||||
/*
|
||||
construct a MprVar from a list
|
||||
*/
|
||||
struct MprVar mprList(const char *name, const char **list)
|
||||
{
|
||||
struct MprVar var;
|
||||
int i;
|
||||
|
||||
var = mprCreateObjVar(name, MPR_DEFAULT_HASH_SIZE);
|
||||
for (i=0;list && list[i];i++) {
|
||||
mprAddArray(&var, i, mprCreateStringVar(list[i], 1));
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
/*
|
||||
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(), p, length);
|
||||
if (s == NULL) {
|
||||
return mprCreateUndefinedVar();
|
||||
}
|
||||
var = mprCreateStringVar(s, 1);
|
||||
talloc_free(s);
|
||||
return var;
|
||||
}
|
||||
|
||||
/*
|
||||
turn a ldb_message into a ejs object variable
|
||||
*/
|
||||
struct MprVar mprLdbMessage(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 };
|
||||
struct MprVar val;
|
||||
|
||||
var = mprCreateObjVar(msg->dn, MPR_DEFAULT_HASH_SIZE);
|
||||
|
||||
for (i=0;i<msg->num_elements;i++) {
|
||||
struct ldb_message_element *el = &msg->elements[i];
|
||||
if (el->num_values == 1 &&
|
||||
!str_list_check_ci(multivalued, el->name)) {
|
||||
val = mprData(el->values[0].data, el->values[0].length);
|
||||
} else {
|
||||
int j;
|
||||
val = mprCreateObjVar(el->name, MPR_DEFAULT_HASH_SIZE);
|
||||
for (j=0;j<el->num_values;j++) {
|
||||
mprAddArray(&val, j,
|
||||
mprData(el->values[j].data,
|
||||
el->values[j].length));
|
||||
}
|
||||
}
|
||||
mprCreateProperty(&var, el->name, &val);
|
||||
}
|
||||
|
||||
/* add the dn if it is not already specified */
|
||||
if (mprGetProperty(&var, "dn", 0) == 0) {
|
||||
val = mprCreateStringVar(msg->dn, 1);
|
||||
mprCreateProperty(&var, "dn", &val);
|
||||
}
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
turn an array of ldb_messages into a ejs object variable
|
||||
*/
|
||||
struct MprVar mprLdbArray(struct ldb_message **msg, int count, const char *name)
|
||||
{
|
||||
struct MprVar res;
|
||||
int i;
|
||||
|
||||
res = mprCreateObjVar(name?name:"(NULL)", MPR_DEFAULT_HASH_SIZE);
|
||||
for (i=0;i<count;i++) {
|
||||
mprAddArray(&res, i, mprLdbMessage(msg[i]));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
turn a MprVar string variable into a const char *
|
||||
*/
|
||||
const char *mprToString(const struct MprVar *v)
|
||||
{
|
||||
if (v->type != MPR_TYPE_STRING) return NULL;
|
||||
return v->string;
|
||||
}
|
||||
|
||||
/*
|
||||
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;
|
||||
}
|
||||
|
259
source/scripting/ejs/smbcalls.c
Normal file
259
source/scripting/ejs/smbcalls.c
Normal file
@ -0,0 +1,259 @@
|
||||
/*
|
||||
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 "lib/ejs/ejs.h"
|
||||
#include "param/loadparm.h"
|
||||
#include "lib/ldb/include/ldb.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, "null" },
|
||||
{ MPR_TYPE_BOOL, "boolean" },
|
||||
{ MPR_TYPE_CFUNCTION, "function" },
|
||||
{ MPR_TYPE_FLOAT, "float" },
|
||||
{ MPR_TYPE_INT, "int" },
|
||||
{ MPR_TYPE_INT64, "int64" },
|
||||
{ MPR_TYPE_OBJECT, "object" },
|
||||
{ MPR_TYPE_FUNCTION, "function" },
|
||||
{ MPR_TYPE_STRING, "string" },
|
||||
{ MPR_TYPE_STRING_CFUNCTION, "function" }
|
||||
};
|
||||
int i;
|
||||
const char *type = "unknown";
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
ejsSetReturnString(eid, type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
setup a return of a string list
|
||||
*/
|
||||
static void ejs_returnlist(MprVarHandle eid,
|
||||
const char *name, const char **list)
|
||||
{
|
||||
ejsSetReturnValue(eid, mprList(name, list));
|
||||
}
|
||||
|
||||
/*
|
||||
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);
|
||||
ejs_returnlist(eid, "services", list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
allow access to loadparm variables from inside ejs scripts in swat
|
||||
|
||||
can be called in 4 ways:
|
||||
|
||||
v = lpGet("type:parm"); gets a parametric variable
|
||||
v = lpGet("share", "type:parm"); gets a parametric variable on a share
|
||||
v = lpGet("parm"); gets a global variable
|
||||
v = lpGet("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;
|
||||
ejsSetReturnString(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;
|
||||
ejsSetReturnString(eid, value);
|
||||
return 0;
|
||||
} else {
|
||||
/* its a global parameter */
|
||||
parm = lp_parm_struct(argv[0]);
|
||||
if (parm == NULL) return -1;
|
||||
parm_ptr = parm->ptr;
|
||||
}
|
||||
|
||||
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:
|
||||
ejsSetReturnString(eid, *(char **)parm_ptr);
|
||||
break;
|
||||
case P_BOOL:
|
||||
ejsSetReturnValue(eid, mprCreateBoolVar(*(BOOL *)parm_ptr));
|
||||
break;
|
||||
case P_INTEGER:
|
||||
ejsSetReturnValue(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) {
|
||||
ejsSetReturnString(eid, parm->enum_list[i].name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
case P_LIST:
|
||||
ejs_returnlist(eid, parm->label, *(const char ***)parm_ptr);
|
||||
break;
|
||||
case P_SEP:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
perform an ldb search, returning an array of results
|
||||
|
||||
syntax:
|
||||
ldbSearch("dbfile", "expression");
|
||||
var attrs = new Array("attr1", "attr2", "attr3");
|
||||
ldbSearch("dbfile", "expression", attrs);
|
||||
*/
|
||||
static int ejs_ldbSearch(MprVarHandle eid, int argc, struct MprVar **argv)
|
||||
{
|
||||
const char **attrs = NULL;
|
||||
const char *expression, *dbfile;
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(mprMemCtx());
|
||||
struct ldb_context *ldb;
|
||||
int ret;
|
||||
struct ldb_message **res;
|
||||
|
||||
/* validate arguments */
|
||||
if (argc < 2 || argc > 3 ||
|
||||
argv[0]->type != MPR_TYPE_STRING) {
|
||||
ejsSetErrorMsg(eid, "ldbSearch invalid arguments");
|
||||
goto failed;
|
||||
}
|
||||
if (argc == 3 && argv[2]->type != MPR_TYPE_OBJECT) {
|
||||
ejsSetErrorMsg(eid, "ldbSearch attributes must be an object");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
dbfile = mprToString(argv[0]);
|
||||
expression = mprToString(argv[1]);
|
||||
if (argc > 2) {
|
||||
attrs = mprToList(tmp_ctx, argv[2]);
|
||||
}
|
||||
if (dbfile == NULL || expression == NULL) {
|
||||
ejsSetErrorMsg(eid, "ldbSearch invalid arguments");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ldb = ldb_wrap_connect(tmp_ctx, dbfile, 0, NULL);
|
||||
if (ldb == NULL) {
|
||||
ejsSetErrorMsg(eid, "ldbSearch failed to open %s", dbfile);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ret = ldb_search(ldb, NULL, LDB_SCOPE_DEFAULT, expression, attrs, &res);
|
||||
if (ret == -1) {
|
||||
ejsSetErrorMsg(eid, "ldbSearch failed - %s", ldb_errstring(ldb));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ejsSetReturnValue(eid, mprLdbArray(res, ret, "ldb_message"));
|
||||
|
||||
talloc_free(tmp_ctx);
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
talloc_free(tmp_ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
setup the C functions that be called from ejs
|
||||
*/
|
||||
void smb_setup_ejs_functions(void)
|
||||
{
|
||||
ejsDefineStringCFunction(-1, "lpGet", ejs_lpGet, NULL, 0);
|
||||
ejsDefineStringCFunction(-1, "lpServices", ejs_lpServices, NULL, 0);
|
||||
ejsDefineCFunction(-1, "typeof", ejs_typeof, NULL, 0);
|
||||
ejsDefineCFunction(-1, "ldbSearch", ejs_ldbSearch, NULL, 0);
|
||||
}
|
@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "dynconfig.h"
|
||||
#include "lib/ejs/ejs.h"
|
||||
|
||||
void ejs_exception(const char *reason)
|
||||
@ -29,36 +30,36 @@ void ejs_exception(const char *reason)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int writeProc(MprVarHandle userHandle, int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
mprAssert(argv);
|
||||
for (i = 0; i < argc; i++) {
|
||||
printf("%s", argv[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
EjsId eid;
|
||||
EjsHandle handle;
|
||||
MprVar result;
|
||||
char *emsg;
|
||||
TALLOC_CTX *mem_ctx = talloc_new(NULL);
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s <scriptfile>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
setup_logging(argv[0],DEBUG_STDOUT);
|
||||
|
||||
if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
|
||||
fprintf(stderr, "%s: Can't load %s - run testparm to debug it\n",
|
||||
argv[0], dyn_CONFIGFILE);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
mprSetCtx(mem_ctx);
|
||||
|
||||
if (ejsOpen(NULL, NULL, NULL) != 0) {
|
||||
fprintf(stderr, "smbscript: ejsOpen(): unable to initialise "
|
||||
"EJ subsystem\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ejsDefineStringCFunction(-1, "write", writeProc, NULL, 0);
|
||||
smb_setup_ejs_functions();
|
||||
|
||||
if ((eid = ejsOpenEngine(handle, 0)) == (EjsId)-1) {
|
||||
fprintf(stderr, "smbscript: ejsOpenEngine(): unable to "
|
||||
@ -74,5 +75,7 @@ static int writeProc(MprVarHandle userHandle, int argc, char **argv)
|
||||
|
||||
ejsClose();
|
||||
|
||||
talloc_free(mem_ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,357 +26,6 @@
|
||||
#include "param/loadparm.h"
|
||||
#include "lib/ldb/include/ldb.h"
|
||||
|
||||
/*
|
||||
add an indexed array element to a property
|
||||
*/
|
||||
static void mprAddArray(struct MprVar *var, int i, struct MprVar v)
|
||||
{
|
||||
char idx[16];
|
||||
mprItoa(i, idx, sizeof(idx));
|
||||
mprCreateProperty(var, idx, &v);
|
||||
}
|
||||
|
||||
/*
|
||||
construct a MprVar from a list
|
||||
*/
|
||||
static struct MprVar mprList(const char *name, const char **list)
|
||||
{
|
||||
struct MprVar var;
|
||||
int i;
|
||||
|
||||
var = mprCreateObjVar(name, ESP_HASH_SIZE);
|
||||
for (i=0;list && list[i];i++) {
|
||||
mprAddArray(&var, i, mprCreateStringVar(list[i], 1));
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
/*
|
||||
construct a string MprVar from a lump of data
|
||||
*/
|
||||
static struct MprVar mprData(const uint8_t *p, size_t length)
|
||||
{
|
||||
struct MprVar var;
|
||||
char *s = talloc_strndup(NULL, p, length);
|
||||
if (s == NULL) {
|
||||
return mprCreateUndefinedVar();
|
||||
}
|
||||
var = mprCreateStringVar(s, 1);
|
||||
talloc_free(s);
|
||||
return var;
|
||||
}
|
||||
|
||||
/*
|
||||
turn a ldb_message into a ejs object variable
|
||||
*/
|
||||
static struct MprVar mprLdbMessage(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 };
|
||||
struct MprVar val;
|
||||
|
||||
var = mprCreateObjVar(msg->dn, ESP_HASH_SIZE);
|
||||
|
||||
for (i=0;i<msg->num_elements;i++) {
|
||||
struct ldb_message_element *el = &msg->elements[i];
|
||||
if (el->num_values == 1 &&
|
||||
!str_list_check_ci(multivalued, el->name)) {
|
||||
val = mprData(el->values[0].data, el->values[0].length);
|
||||
} else {
|
||||
int j;
|
||||
val = mprCreateObjVar(el->name, ESP_HASH_SIZE);
|
||||
for (j=0;j<el->num_values;j++) {
|
||||
mprAddArray(&val, j,
|
||||
mprData(el->values[j].data,
|
||||
el->values[j].length));
|
||||
}
|
||||
}
|
||||
mprCreateProperty(&var, el->name, &val);
|
||||
}
|
||||
|
||||
/* add the dn if it is not already specified */
|
||||
if (mprGetProperty(&var, "dn", 0) == 0) {
|
||||
val = mprCreateStringVar(msg->dn, 1);
|
||||
mprCreateProperty(&var, "dn", &val);
|
||||
}
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
turn an array of ldb_messages into a ejs object variable
|
||||
*/
|
||||
static struct MprVar mprLdbArray(struct ldb_message **msg, int count,
|
||||
const char *name)
|
||||
{
|
||||
struct MprVar res;
|
||||
int i;
|
||||
|
||||
res = mprCreateObjVar(name?name:"(NULL)", ESP_HASH_SIZE);
|
||||
for (i=0;i<count;i++) {
|
||||
mprAddArray(&res, i, mprLdbMessage(msg[i]));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
turn a MprVar string variable into a const char *
|
||||
*/
|
||||
static const char *mprToString(const struct MprVar *v)
|
||||
{
|
||||
if (v->type != MPR_TYPE_STRING) return NULL;
|
||||
return v->string;
|
||||
}
|
||||
|
||||
/*
|
||||
turn a MprVar object variable into a string list
|
||||
this assumes the object variable consists only of strings
|
||||
*/
|
||||
static 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;
|
||||
}
|
||||
|
||||
/*
|
||||
return the type of a variable
|
||||
*/
|
||||
static int esp_typeof(struct EspRequest *ep, 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, "function" },
|
||||
{ MPR_TYPE_FLOAT, "float" },
|
||||
{ MPR_TYPE_INT, "int" },
|
||||
{ MPR_TYPE_INT64, "int64" },
|
||||
{ MPR_TYPE_OBJECT, "object" },
|
||||
{ MPR_TYPE_FUNCTION, "function" },
|
||||
{ MPR_TYPE_STRING, "string" },
|
||||
{ MPR_TYPE_STRING_CFUNCTION, "function" }
|
||||
};
|
||||
int i;
|
||||
const char *type = "unknown";
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
espSetReturnString(ep, type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
setup a return of a string list
|
||||
*/
|
||||
static void esp_returnlist(struct EspRequest *ep,
|
||||
const char *name, const char **list)
|
||||
{
|
||||
espSetReturn(ep, mprList(name, list));
|
||||
}
|
||||
|
||||
/*
|
||||
return a list of defined services
|
||||
*/
|
||||
static int esp_lpServices(struct EspRequest *ep, 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(ep, list);
|
||||
esp_returnlist(ep, "services", list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
allow access to loadparm variables from inside esp scripts in swat
|
||||
|
||||
can be called in 4 ways:
|
||||
|
||||
v = lpGet("type:parm"); gets a parametric variable
|
||||
v = lpGet("share", "type:parm"); gets a parametric variable on a share
|
||||
v = lpGet("parm"); gets a global variable
|
||||
v = lpGet("share", "parm"); gets a share variable
|
||||
|
||||
the returned variable is a ejs object. It is an array object for lists.
|
||||
*/
|
||||
static int esp_lpGet(struct EspRequest *ep, 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(ep, 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;
|
||||
espSetReturnString(ep, 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(ep, 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;
|
||||
espSetReturnString(ep, value);
|
||||
return 0;
|
||||
} else {
|
||||
/* its a global parameter */
|
||||
parm = lp_parm_struct(argv[0]);
|
||||
if (parm == NULL) return -1;
|
||||
parm_ptr = parm->ptr;
|
||||
}
|
||||
|
||||
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:
|
||||
espSetReturnString(ep, *(char **)parm_ptr);
|
||||
break;
|
||||
case P_BOOL:
|
||||
espSetReturn(ep, mprCreateBoolVar(*(BOOL *)parm_ptr));
|
||||
break;
|
||||
case P_INTEGER:
|
||||
espSetReturn(ep, 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) {
|
||||
espSetReturnString(ep, parm->enum_list[i].name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
case P_LIST:
|
||||
esp_returnlist(ep, parm->label, *(const char ***)parm_ptr);
|
||||
break;
|
||||
case P_SEP:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
perform an ldb search, returning an array of results
|
||||
|
||||
syntax:
|
||||
ldbSearch("dbfile", "expression");
|
||||
var attrs = new Array("attr1", "attr2", "attr3");
|
||||
ldbSearch("dbfile", "expression", attrs);
|
||||
*/
|
||||
static int esp_ldbSearch(struct EspRequest *ep, int argc, struct MprVar **argv)
|
||||
{
|
||||
const char **attrs = NULL;
|
||||
const char *expression, *dbfile;
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(ep);
|
||||
struct ldb_context *ldb;
|
||||
int ret;
|
||||
struct ldb_message **res;
|
||||
|
||||
/* validate arguments */
|
||||
if (argc < 2 || argc > 3 ||
|
||||
argv[0]->type != MPR_TYPE_STRING) {
|
||||
espError(ep, "ldbSearch invalid arguments");
|
||||
goto failed;
|
||||
}
|
||||
if (argc == 3 && argv[2]->type != MPR_TYPE_OBJECT) {
|
||||
espError(ep, "ldbSearch attributes must be an object");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
dbfile = mprToString(argv[0]);
|
||||
expression = mprToString(argv[1]);
|
||||
if (argc > 2) {
|
||||
attrs = mprToList(tmp_ctx, argv[2]);
|
||||
}
|
||||
if (dbfile == NULL || expression == NULL) {
|
||||
espError(ep, "ldbSearch invalid arguments");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ldb = ldb_wrap_connect(tmp_ctx, dbfile, 0, NULL);
|
||||
if (ldb == NULL) {
|
||||
espError(ep, "ldbSearch failed to open %s", dbfile);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ret = ldb_search(ldb, NULL, LDB_SCOPE_DEFAULT, expression, attrs, &res);
|
||||
if (ret == -1) {
|
||||
espError(ep, "ldbSearch failed - %s", ldb_errstring(ldb));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
espSetReturn(ep, mprLdbArray(res, ret, "ldb_message"));
|
||||
|
||||
talloc_free(tmp_ctx);
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
talloc_free(tmp_ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* try to authenticate the user/password pair against system auth mechanisms
|
||||
returns 0 on success
|
||||
@ -452,9 +101,5 @@ done:
|
||||
*/
|
||||
void http_setup_ejs_functions(void)
|
||||
{
|
||||
espDefineStringCFunction(NULL, "lpGet", esp_lpGet, NULL);
|
||||
espDefineStringCFunction(NULL, "lpServices", esp_lpServices, NULL);
|
||||
espDefineCFunction(NULL, "typeof", esp_typeof, NULL);
|
||||
espDefineCFunction(NULL, "ldbSearch", esp_ldbSearch, NULL);
|
||||
espDefineCFunction(NULL, "unixAuth", esp_unixAuth, NULL);
|
||||
}
|
||||
|
@ -24,6 +24,6 @@ ADD_OBJ_FILES = \
|
||||
web_server/tls.o \
|
||||
web_server/tlscert.o \
|
||||
web_server/pam.o
|
||||
REQUIRED_SUBSYSTEMS = ESP EXT_LIB_GNUTLS EXT_LIB_PAM
|
||||
REQUIRED_SUBSYSTEMS = ESP EXT_LIB_GNUTLS EXT_LIB_PAM SMBCALLS
|
||||
# End SUBSYSTEM WEB
|
||||
#######################
|
||||
|
@ -749,7 +749,7 @@ void http_process_input(struct websrv_context *web)
|
||||
|
||||
talloc_set_destructor(esp, esp_destructor);
|
||||
|
||||
http_setup_ejs_functions();
|
||||
smb_setup_ejs_functions();
|
||||
|
||||
esp->req = espCreateRequest(web, web->input.url, esp->variables);
|
||||
if (esp->req == NULL) goto internal_error;
|
||||
|
Loading…
Reference in New Issue
Block a user