r4348: syncing up for 3.0.11pre1
[Samba.git] / source / python / py_common.c
blob66f35759c3d6d56b2c4c6600a79b8699d4e90eff
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 "python/py_common.h"
23 /* Return a tuple of (error code, error string) from a WERROR */
25 PyObject *py_werror_tuple(WERROR werror)
27 return Py_BuildValue("[is]", W_ERROR_V(werror),
28 dos_errstr(werror));
31 /* Return a tuple of (error code, error string) from a WERROR */
33 PyObject *py_ntstatus_tuple(NTSTATUS ntstatus)
35 return Py_BuildValue("[is]", NT_STATUS_V(ntstatus),
36 nt_errstr(ntstatus));
39 /* Initialise samba client routines */
41 static BOOL initialised;
43 void py_samba_init(void)
45 if (initialised)
46 return;
48 /* Load configuration file */
50 if (!lp_load(dyn_CONFIGFILE, True, False, False))
51 fprintf(stderr, "Can't load %s\n", dyn_CONFIGFILE);
53 /* Misc other stuff */
55 load_interfaces();
56 init_names();
58 initialised = True;
61 /* Debuglevel routines */
63 PyObject *get_debuglevel(PyObject *self, PyObject *args)
65 PyObject *debuglevel;
67 if (!PyArg_ParseTuple(args, ""))
68 return NULL;
70 debuglevel = PyInt_FromLong(DEBUGLEVEL);
72 return debuglevel;
75 PyObject *set_debuglevel(PyObject *self, PyObject *args)
77 int debuglevel;
79 if (!PyArg_ParseTuple(args, "i", &debuglevel))
80 return NULL;
82 DEBUGLEVEL = debuglevel;
84 Py_INCREF(Py_None);
85 return Py_None;
88 /* Initialise logging */
90 PyObject *py_setup_logging(PyObject *self, PyObject *args, PyObject *kw)
92 BOOL interactive = False;
93 char *logfilename = NULL;
94 static char *kwlist[] = {"interactive", "logfilename", NULL};
96 if (!PyArg_ParseTupleAndKeywords(
97 args, kw, "|is", kwlist, &interactive, &logfilename))
98 return NULL;
100 if (interactive && logfilename) {
101 PyErr_SetString(PyExc_RuntimeError,
102 "can't be interactive and set log file name");
103 return NULL;
106 if (interactive)
107 setup_logging("spoolss", True);
109 if (logfilename) {
110 lp_set_logfile(logfilename);
111 setup_logging(logfilename, False);
112 reopen_logs();
115 Py_INCREF(Py_None);
116 return Py_None;
119 /* Parse credentials from a python dictionary. The dictionary can
120 only have the keys "username", "domain" and "password". Return
121 True for valid credentials in which case the username, domain and
122 password are set to pointers to their values from the dicationary.
123 If returns False, the errstr is set to point at some mallocated
124 memory describing the error. */
126 BOOL py_parse_creds(PyObject *creds, char **username, char **domain,
127 char **password, char **errstr)
129 /* Initialise anonymous credentials */
131 *username = "";
132 *domain = "";
133 *password = "";
135 if (creds && PyDict_Size(creds) > 0) {
136 PyObject *username_obj, *password_obj, *domain_obj;
137 PyObject *key, *value;
138 int i;
140 /* Check for presence of required fields */
142 username_obj = PyDict_GetItemString(creds, "username");
143 domain_obj = PyDict_GetItemString(creds, "domain");
144 password_obj = PyDict_GetItemString(creds, "password");
146 if (!username_obj) {
147 *errstr = SMB_STRDUP("no username field in credential");
148 return False;
151 if (!domain_obj) {
152 *errstr = SMB_STRDUP("no domain field in credential");
153 return False;
156 if (!password_obj) {
157 *errstr = SMB_STRDUP("no password field in credential");
158 return False;
161 /* Check type of required fields */
163 if (!PyString_Check(username_obj)) {
164 *errstr = SMB_STRDUP("username field is not string type");
165 return False;
168 if (!PyString_Check(domain_obj)) {
169 *errstr = SMB_STRDUP("domain field is not string type");
170 return False;
173 if (!PyString_Check(password_obj)) {
174 *errstr = SMB_STRDUP("password field is not string type");
175 return False;
178 /* Look for any extra fields */
180 i = 0;
182 while (PyDict_Next(creds, &i, &key, &value)) {
183 if (strcmp(PyString_AsString(key), "domain") != 0 &&
184 strcmp(PyString_AsString(key), "username") != 0 &&
185 strcmp(PyString_AsString(key), "password") != 0) {
186 asprintf(errstr,
187 "creds contain extra field '%s'",
188 PyString_AsString(key));
189 return False;
193 /* Assign values */
195 *username = PyString_AsString(username_obj);
196 *domain = PyString_AsString(domain_obj);
197 *password = PyString_AsString(password_obj);
200 *errstr = NULL;
202 return True;
205 /* Return a cli_state to a RPC pipe on the given server. Use the
206 credentials passed if not NULL. If an error occurs errstr is set to a
207 string describing the error and NULL is returned. If set, errstr must
208 be freed by calling free(). */
210 struct cli_state *open_pipe_creds(char *server, PyObject *creds,
211 int pipe_idx, char **errstr)
213 char *username, *password, *domain;
214 struct cli_state *cli;
215 NTSTATUS result;
217 /* Extract credentials from the python dictionary */
219 if (!py_parse_creds(creds, &username, &domain, &password, errstr))
220 return NULL;
222 /* Now try to connect */
224 result = cli_full_connection(
225 &cli, NULL, server, NULL, 0, "IPC$", "IPC",
226 username, domain, password, 0, Undefined, NULL);
228 if (!NT_STATUS_IS_OK(result)) {
229 *errstr = SMB_STRDUP("error connecting to IPC$ pipe");
230 return NULL;
233 if (!cli_nt_session_open(cli, pipe_idx)) {
234 cli_shutdown(cli);
235 asprintf(errstr, "error opening pipe index %d", pipe_idx);
236 return NULL;
239 *errstr = NULL;
241 return cli;
244 /* Return true if a dictionary contains a "level" key with an integer
245 value. Set the value if so. */
247 BOOL get_level_value(PyObject *dict, uint32 *level)
249 PyObject *obj;
251 if (!(obj = PyDict_GetItemString(dict, "level")) ||
252 !PyInt_Check(obj))
253 return False;
255 if (level)
256 *level = PyInt_AsLong(obj);
258 return True;