Add extra parm to cli_full_connection call. Tim, you should probably look at this.
[Samba/gebeck_regimport.git] / source3 / python / py_common.c
blob364271d57c4aa05bf9d2563d3099808c1b78ff8f
1 /*
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 2 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, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "includes.h"
22 #include "Python.h"
24 #include "python/py_common_proto.h"
26 /* Return a tuple of (error code, error string) from a WERROR */
28 PyObject *py_werror_tuple(WERROR werror)
30 return Py_BuildValue("[is]", W_ERROR_V(werror),
31 dos_errstr(werror));
34 /* Return a tuple of (error code, error string) from a WERROR */
36 PyObject *py_ntstatus_tuple(NTSTATUS ntstatus)
38 return Py_BuildValue("[is]", NT_STATUS_V(ntstatus),
39 nt_errstr(ntstatus));
42 /* Initialise samba client routines */
44 static BOOL initialised;
46 void py_samba_init(void)
48 extern pstring global_myname;
49 char *p;
51 if (initialised)
52 return;
54 /* Load configuration file */
56 if (!lp_load(dyn_CONFIGFILE, True, False, False))
57 fprintf(stderr, "Can't load %s\n", dyn_CONFIGFILE);
59 /* Misc other stuff */
61 load_interfaces();
63 fstrcpy(global_myname, myhostname());
64 p = strchr(global_myname, '.');
65 if (p)
66 *p = 0;
68 initialised = True;
71 /* Debuglevel routines */
73 PyObject *get_debuglevel(PyObject *self, PyObject *args)
75 PyObject *debuglevel;
77 if (!PyArg_ParseTuple(args, ""))
78 return NULL;
80 debuglevel = PyInt_FromLong(DEBUGLEVEL);
82 return debuglevel;
85 PyObject *set_debuglevel(PyObject *self, PyObject *args)
87 int debuglevel;
89 if (!PyArg_ParseTuple(args, "i", &debuglevel))
90 return NULL;
92 DEBUGLEVEL = debuglevel;
94 Py_INCREF(Py_None);
95 return Py_None;
98 /* Initialise logging */
100 PyObject *py_setup_logging(PyObject *self, PyObject *args, PyObject *kw)
102 BOOL interactive = False;
103 char *logfilename = NULL;
104 static char *kwlist[] = {"interactive", "logfilename", NULL};
106 if (!PyArg_ParseTupleAndKeywords(
107 args, kw, "|is", kwlist, &interactive, &logfilename))
108 return NULL;
110 if (interactive && logfilename) {
111 PyErr_SetString(PyExc_RuntimeError,
112 "can't be interactive and set log file name");
113 return NULL;
116 if (interactive)
117 setup_logging("spoolss", True);
119 if (logfilename) {
120 lp_set_logfile(logfilename);
121 setup_logging(logfilename, False);
122 reopen_logs();
125 Py_INCREF(Py_None);
126 return Py_None;
129 /* Parse credentials from a python dictionary. The dictionary can
130 only have the keys "username", "domain" and "password". Return
131 True for valid credentials in which case the username, domain and
132 password are set to pointers to their values from the dicationary.
133 If returns False, the errstr is set to point at some mallocated
134 memory describing the error. */
136 BOOL py_parse_creds(PyObject *creds, char **username, char **domain,
137 char **password, char **errstr)
139 /* Initialise anonymous credentials */
141 *username = "";
142 *domain = "";
143 *password = "";
145 if (creds && PyDict_Size(creds) > 0) {
146 PyObject *username_obj, *password_obj, *domain_obj;
147 PyObject *key, *value;
148 int i;
150 /* Check for presence of required fields */
152 username_obj = PyDict_GetItemString(creds, "username");
153 domain_obj = PyDict_GetItemString(creds, "domain");
154 password_obj = PyDict_GetItemString(creds, "password");
156 if (!username_obj) {
157 *errstr = strdup("no username field in credential");
158 return False;
161 if (!domain_obj) {
162 *errstr = strdup("no domain field in credential");
163 return False;
166 if (!password_obj) {
167 *errstr = strdup("no password field in credential");
168 return False;
171 /* Check type of required fields */
173 if (!PyString_Check(username_obj)) {
174 *errstr = strdup("username field is not string type");
175 return False;
178 if (!PyString_Check(domain_obj)) {
179 *errstr = strdup("domain field is not string type");
180 return False;
183 if (!PyString_Check(password_obj)) {
184 *errstr = strdup("password field is not string type");
185 return False;
188 /* Look for any extra fields */
190 i = 0;
192 while (PyDict_Next(creds, &i, &key, &value)) {
193 if (strcmp(PyString_AsString(key), "domain") != 0 &&
194 strcmp(PyString_AsString(key), "username") != 0 &&
195 strcmp(PyString_AsString(key), "password") != 0) {
196 asprintf(errstr,
197 "creds contain extra field '%s'",
198 PyString_AsString(key));
199 return False;
203 /* Assign values */
205 *username = PyString_AsString(username_obj);
206 *domain = PyString_AsString(domain_obj);
207 *password = PyString_AsString(password_obj);
210 *errstr = NULL;
212 return True;
215 /* Return a cli_state to a RPC pipe on the given server. Use the
216 credentials passed if not NULL. If an error occurs errstr is set to a
217 string describing the error and NULL is returned. If set, errstr must
218 be freed by calling free(). */
220 struct cli_state *open_pipe_creds(char *server, PyObject *creds,
221 int pipe_idx, char **errstr)
223 char *username, *password, *domain;
224 struct cli_state *cli;
225 NTSTATUS result;
227 /* Extract credentials from the python dictionary */
229 if (!py_parse_creds(creds, &username, &domain, &password, errstr))
230 return NULL;
232 /* Now try to connect */
234 result = cli_full_connection(
235 &cli, NULL, server, NULL, 0, "IPC$", "IPC",
236 username, domain, password, 0, NULL);
238 if (!NT_STATUS_IS_OK(result)) {
239 *errstr = strdup("error connecting to IPC$ pipe");
240 return NULL;
243 if (!cli_nt_session_open(cli, pipe_idx)) {
244 cli_shutdown(cli);
245 asprintf(errstr, "error opening pipe index %d", pipe_idx);
246 return NULL;
249 *errstr = NULL;
251 return cli;
254 /* Return true if a dictionary contains a "level" key with an integer
255 value. Set the value if so. */
257 BOOL get_level_value(PyObject *dict, uint32 *level)
259 PyObject *obj;
261 if (!(obj = PyDict_GetItemString(dict, "level")) ||
262 !PyInt_Check(obj))
263 return False;
265 if (level)
266 *level = PyInt_AsLong(obj);
268 return True;