2 Python wrappers for DCERPC/SMB client routines.
4 Copyright (C) Tim Potter, 2002
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "python/py_common.h"
22 /* Return a tuple of (error code, error string) from a WERROR */
24 PyObject *py_werror_tuple(WERROR werror)
26 return Py_BuildValue("[is]", W_ERROR_V(werror),
30 /* Return a tuple of (error code, error string) from a WERROR */
32 PyObject *py_ntstatus_tuple(NTSTATUS ntstatus)
34 return Py_BuildValue("[is]", NT_STATUS_V(ntstatus),
38 /* Initialise samba client routines */
40 static BOOL initialised;
42 void py_samba_init(void)
49 /* Load configuration file */
51 if (!lp_load(dyn_CONFIGFILE, True, False, False, True))
52 fprintf(stderr, "Can't load %s\n", dyn_CONFIGFILE);
54 /* Misc other stuff */
62 /* Debuglevel routines */
64 PyObject *get_debuglevel(PyObject *self, PyObject *args)
68 if (!PyArg_ParseTuple(args, ""))
71 debuglevel = PyInt_FromLong(DEBUGLEVEL);
76 PyObject *set_debuglevel(PyObject *self, PyObject *args)
80 if (!PyArg_ParseTuple(args, "i", &debuglevel))
83 DEBUGLEVEL = debuglevel;
89 /* Initialise logging */
91 PyObject *py_setup_logging(PyObject *self, PyObject *args, PyObject *kw)
93 BOOL interactive = False;
94 char *logfilename = NULL;
95 static char *kwlist[] = {"interactive", "logfilename", NULL};
97 if (!PyArg_ParseTupleAndKeywords(
98 args, kw, "|is", kwlist, &interactive, &logfilename))
101 if (interactive && logfilename) {
102 PyErr_SetString(PyExc_RuntimeError,
103 "can't be interactive and set log file name");
108 setup_logging("spoolss", True);
111 lp_set_logfile(logfilename);
112 setup_logging(logfilename, False);
120 /* Parse credentials from a python dictionary. The dictionary can
121 only have the keys "username", "domain" and "password". Return
122 True for valid credentials in which case the username, domain and
123 password are set to pointers to their values from the dicationary.
124 If returns False, the errstr is set to point at some mallocated
125 memory describing the error. */
127 BOOL py_parse_creds(PyObject *creds, char **username, char **domain,
128 char **password, char **errstr)
130 /* Initialise anonymous credentials */
136 if (creds && PyDict_Size(creds) > 0) {
137 PyObject *username_obj, *password_obj, *domain_obj;
138 PyObject *key, *value;
141 /* Check for presence of required fields */
143 username_obj = PyDict_GetItemString(creds, "username");
144 domain_obj = PyDict_GetItemString(creds, "domain");
145 password_obj = PyDict_GetItemString(creds, "password");
148 *errstr = SMB_STRDUP("no username field in credential");
153 *errstr = SMB_STRDUP("no domain field in credential");
158 *errstr = SMB_STRDUP("no password field in credential");
162 /* Check type of required fields */
164 if (!PyString_Check(username_obj)) {
165 *errstr = SMB_STRDUP("username field is not string type");
169 if (!PyString_Check(domain_obj)) {
170 *errstr = SMB_STRDUP("domain field is not string type");
174 if (!PyString_Check(password_obj)) {
175 *errstr = SMB_STRDUP("password field is not string type");
179 /* Look for any extra fields */
183 while (PyDict_Next(creds, &i, &key, &value)) {
184 if (strcmp(PyString_AsString(key), "domain") != 0 &&
185 strcmp(PyString_AsString(key), "username") != 0 &&
186 strcmp(PyString_AsString(key), "password") != 0) {
188 "creds contain extra field '%s'",
189 PyString_AsString(key));
196 *username = PyString_AsString(username_obj);
197 *domain = PyString_AsString(domain_obj);
198 *password = PyString_AsString(password_obj);
206 /* Return a cli_state to a RPC pipe on the given server. Use the
207 credentials passed if not NULL. If an error occurs errstr is set to a
208 string describing the error and NULL is returned. If set, errstr must
209 be freed by calling free(). */
211 struct cli_state *open_pipe_creds(char *server, PyObject *creds,
212 int pipe_idx, char **errstr)
214 char *username, *password, *domain;
215 struct cli_state *cli;
216 struct rpc_pipe_client *pipe_hnd;
219 /* Extract credentials from the python dictionary */
221 if (!py_parse_creds(creds, &username, &domain, &password, errstr))
224 /* Now try to connect */
226 result = cli_full_connection(
227 &cli, NULL, server, NULL, 0, "IPC$", "IPC",
228 username, domain, password, 0, Undefined, NULL);
230 if (!NT_STATUS_IS_OK(result)) {
231 *errstr = SMB_STRDUP("error connecting to IPC$ pipe");
235 pipe_hnd = cli_rpc_pipe_open_noauth(cli, pipe_idx, &result);
238 asprintf(errstr, "error opening pipe index %d", pipe_idx);
247 /* Return true if a dictionary contains a "level" key with an integer
248 value. Set the value if so. */
250 BOOL get_level_value(PyObject *dict, uint32 *level)
254 if (!(obj = PyDict_GetItemString(dict, "level")) ||
259 *level = PyInt_AsLong(obj);