*/
#include "includes.h"
+#include "Python.h"
+
+#include "python/py_common_proto.h"
+
+/* Return a tuple of (error code, error string) from a WERROR */
+
+PyObject *py_werror_tuple(WERROR werror)
+{
+ return Py_BuildValue("[is]", W_ERROR_V(werror),
+ dos_errstr(werror));
+}
+
+/* Return a tuple of (error code, error string) from a WERROR */
+
+PyObject *py_ntstatus_tuple(NTSTATUS ntstatus)
+{
+ return Py_BuildValue("[is]", NT_STATUS_V(ntstatus),
+ nt_errstr(ntstatus));
+}
/* Initialise samba client routines */
void py_samba_init(void)
{
+ extern pstring global_myname;
+ char *p;
+
if (initialised)
return;
- /* FIXME: logging doesn't work very well */
-
- setup_logging("python", True);
-
/* Load configuration file */
if (!lp_load(dyn_CONFIGFILE, True, False, False))
/* Misc other stuff */
load_interfaces();
- DEBUGLEVEL = 10;
+ fstrcpy(global_myname, myhostname());
+ p = strchr(global_myname, '.');
+ if (p)
+ *p = 0;
+
initialised = True;
}
+
+/* Debuglevel routines */
+
+PyObject *get_debuglevel(PyObject *self, PyObject *args)
+{
+ PyObject *debuglevel;
+
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+
+ debuglevel = PyInt_FromLong(DEBUGLEVEL);
+
+ return debuglevel;
+}
+
+PyObject *set_debuglevel(PyObject *self, PyObject *args)
+{
+ int debuglevel;
+
+ if (!PyArg_ParseTuple(args, "i", &debuglevel))
+ return NULL;
+
+ DEBUGLEVEL = debuglevel;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* Initialise logging */
+
+PyObject *py_setup_logging(PyObject *self, PyObject *args, PyObject *kw)
+{
+ BOOL interactive = False;
+ char *logfilename = NULL;
+ static char *kwlist[] = {"interactive", "logfilename", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kw, "|is", kwlist, &interactive, &logfilename))
+ return NULL;
+
+ if (interactive && logfilename) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "can't be interactive and set log file name");
+ return NULL;
+ }
+
+ if (interactive)
+ setup_logging("spoolss", True);
+
+ if (logfilename) {
+ lp_set_logfile(logfilename);
+ setup_logging(logfilename, False);
+ reopen_logs();
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* Parse credentials from a python dictionary. The dictionary can
+ only have the keys "username", "domain" and "password". Return
+ True for valid credentials in which case the username, domain and
+ password are set to pointers to their values from the dicationary.
+ If returns False, the errstr is set to point at some mallocated
+ memory describing the error. */
+
+BOOL py_parse_creds(PyObject *creds, char **username, char **domain,
+ char **password, char **errstr)
+{
+ /* Initialise anonymous credentials */
+
+ *username = "";
+ *domain = "";
+ *password = "";
+
+ if (creds && PyDict_Size(creds) > 0) {
+ PyObject *username_obj, *password_obj, *domain_obj;
+ PyObject *key, *value;
+ int i;
+
+ /* Check for presence of required fields */
+
+ username_obj = PyDict_GetItemString(creds, "username");
+ domain_obj = PyDict_GetItemString(creds, "domain");
+ password_obj = PyDict_GetItemString(creds, "password");
+
+ if (!username_obj) {
+ *errstr = strdup("no username field in credential");
+ return False;
+ }
+
+ if (!domain_obj) {
+ *errstr = strdup("no domain field in credential");
+ return False;
+ }
+
+ if (!password_obj) {
+ *errstr = strdup("no password field in credential");
+ return False;
+ }
+
+ /* Check type of required fields */
+
+ if (!PyString_Check(username_obj)) {
+ *errstr = strdup("username field is not string type");
+ return False;
+ }
+
+ if (!PyString_Check(domain_obj)) {
+ *errstr = strdup("domain field is not string type");
+ return False;
+ }
+
+ if (!PyString_Check(password_obj)) {
+ *errstr = strdup("password field is not string type");
+ return False;
+ }
+
+ /* Look for any extra fields */
+
+ i = 0;
+
+ while (PyDict_Next(creds, &i, &key, &value)) {
+ if (strcmp(PyString_AsString(key), "domain") != 0 &&
+ strcmp(PyString_AsString(key), "username") != 0 &&
+ strcmp(PyString_AsString(key), "password") != 0) {
+ asprintf(errstr,
+ "creds contain extra field '%s'",
+ PyString_AsString(key));
+ return False;
+ }
+ }
+
+ /* Assign values */
+
+ *username = PyString_AsString(username_obj);
+ *domain = PyString_AsString(domain_obj);
+ *password = PyString_AsString(password_obj);
+ }
+
+ *errstr = NULL;
+
+ return True;
+}
+
+/* Return a cli_state to a RPC pipe on the given server. Use the
+ credentials passed if not NULL. If an error occurs errstr is set to a
+ string describing the error and NULL is returned. If set, errstr must
+ be freed by calling free(). */
+
+struct cli_state *open_pipe_creds(char *server, PyObject *creds,
+ int pipe_idx, char **errstr)
+{
+ char *username, *password, *domain;
+ struct cli_state *cli;
+ NTSTATUS result;
+
+ /* Extract credentials from the python dictionary */
+
+ if (!py_parse_creds(creds, &username, &domain, &password, errstr))
+ return NULL;
+
+ /* Now try to connect */
+
+ result = cli_full_connection(
+ &cli, NULL, server, NULL, 0, "IPC$", "IPC",
+ username, domain, password, 0, NULL);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ *errstr = strdup("error connecting to IPC$ pipe");
+ return NULL;
+ }
+
+ if (!cli_nt_session_open(cli, pipe_idx)) {
+ cli_shutdown(cli);
+ asprintf(errstr, "error opening pipe index %d", pipe_idx);
+ return NULL;
+ }
+
+ *errstr = NULL;
+
+ return cli;
+}
+
+/* Return true if a dictionary contains a "level" key with an integer
+ value. Set the value if so. */
+
+BOOL get_level_value(PyObject *dict, uint32 *level)
+{
+ PyObject *obj;
+
+ if (!(obj = PyDict_GetItemString(dict, "level")) ||
+ !PyInt_Check(obj))
+ return False;
+
+ if (level)
+ *level = PyInt_AsLong(obj);
+
+ return True;
+}