source: trunk-3.0/source/python/py_common.c@ 102

Last change on this file since 102 was 1, checked in by Paul Smedley, 18 years ago

Initial code import

File size: 6.2 KB
Line 
1/*
2 Python wrappers for DCERPC/SMB client routines.
3
4 Copyright (C) Tim Potter, 2002
5
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.
10
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.
15
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.
19*/
20
21#include "python/py_common.h"
22
23/* Return a tuple of (error code, error string) from a WERROR */
24
25PyObject *py_werror_tuple(WERROR werror)
26{
27 return Py_BuildValue("[is]", W_ERROR_V(werror),
28 dos_errstr(werror));
29}
30
31/* Return a tuple of (error code, error string) from a WERROR */
32
33PyObject *py_ntstatus_tuple(NTSTATUS ntstatus)
34{
35 return Py_BuildValue("[is]", NT_STATUS_V(ntstatus),
36 nt_errstr(ntstatus));
37}
38
39/* Initialise samba client routines */
40
41static BOOL initialised;
42
43void py_samba_init(void)
44{
45 if (initialised)
46 return;
47
48 load_case_tables();
49
50 /* Load configuration file */
51
52 if (!lp_load(dyn_CONFIGFILE, True, False, False, True))
53 fprintf(stderr, "Can't load %s\n", dyn_CONFIGFILE);
54
55 /* Misc other stuff */
56
57 load_interfaces();
58 init_names();
59
60 initialised = True;
61}
62
63/* Debuglevel routines */
64
65PyObject *get_debuglevel(PyObject *self, PyObject *args)
66{
67 PyObject *debuglevel;
68
69 if (!PyArg_ParseTuple(args, ""))
70 return NULL;
71
72 debuglevel = PyInt_FromLong(DEBUGLEVEL);
73
74 return debuglevel;
75}
76
77PyObject *set_debuglevel(PyObject *self, PyObject *args)
78{
79 int debuglevel;
80
81 if (!PyArg_ParseTuple(args, "i", &debuglevel))
82 return NULL;
83
84 DEBUGLEVEL = debuglevel;
85
86 Py_INCREF(Py_None);
87 return Py_None;
88}
89
90/* Initialise logging */
91
92PyObject *py_setup_logging(PyObject *self, PyObject *args, PyObject *kw)
93{
94 BOOL interactive = False;
95 char *logfilename = NULL;
96 static char *kwlist[] = {"interactive", "logfilename", NULL};
97
98 if (!PyArg_ParseTupleAndKeywords(
99 args, kw, "|is", kwlist, &interactive, &logfilename))
100 return NULL;
101
102 if (interactive && logfilename) {
103 PyErr_SetString(PyExc_RuntimeError,
104 "can't be interactive and set log file name");
105 return NULL;
106 }
107
108 if (interactive)
109 setup_logging("spoolss", True);
110
111 if (logfilename) {
112 lp_set_logfile(logfilename);
113 setup_logging(logfilename, False);
114 reopen_logs();
115 }
116
117 Py_INCREF(Py_None);
118 return Py_None;
119}
120
121/* Parse credentials from a python dictionary. The dictionary can
122 only have the keys "username", "domain" and "password". Return
123 True for valid credentials in which case the username, domain and
124 password are set to pointers to their values from the dicationary.
125 If returns False, the errstr is set to point at some mallocated
126 memory describing the error. */
127
128BOOL py_parse_creds(PyObject *creds, char **username, char **domain,
129 char **password, char **errstr)
130{
131 /* Initialise anonymous credentials */
132
133 *username = "";
134 *domain = "";
135 *password = "";
136
137 if (creds && PyDict_Size(creds) > 0) {
138 PyObject *username_obj, *password_obj, *domain_obj;
139 PyObject *key, *value;
140 int i;
141
142 /* Check for presence of required fields */
143
144 username_obj = PyDict_GetItemString(creds, "username");
145 domain_obj = PyDict_GetItemString(creds, "domain");
146 password_obj = PyDict_GetItemString(creds, "password");
147
148 if (!username_obj) {
149 *errstr = SMB_STRDUP("no username field in credential");
150 return False;
151 }
152
153 if (!domain_obj) {
154 *errstr = SMB_STRDUP("no domain field in credential");
155 return False;
156 }
157
158 if (!password_obj) {
159 *errstr = SMB_STRDUP("no password field in credential");
160 return False;
161 }
162
163 /* Check type of required fields */
164
165 if (!PyString_Check(username_obj)) {
166 *errstr = SMB_STRDUP("username field is not string type");
167 return False;
168 }
169
170 if (!PyString_Check(domain_obj)) {
171 *errstr = SMB_STRDUP("domain field is not string type");
172 return False;
173 }
174
175 if (!PyString_Check(password_obj)) {
176 *errstr = SMB_STRDUP("password field is not string type");
177 return False;
178 }
179
180 /* Look for any extra fields */
181
182 i = 0;
183
184 while (PyDict_Next(creds, &i, &key, &value)) {
185 if (strcmp(PyString_AsString(key), "domain") != 0 &&
186 strcmp(PyString_AsString(key), "username") != 0 &&
187 strcmp(PyString_AsString(key), "password") != 0) {
188 asprintf(errstr,
189 "creds contain extra field '%s'",
190 PyString_AsString(key));
191 return False;
192 }
193 }
194
195 /* Assign values */
196
197 *username = PyString_AsString(username_obj);
198 *domain = PyString_AsString(domain_obj);
199 *password = PyString_AsString(password_obj);
200 }
201
202 *errstr = NULL;
203
204 return True;
205}
206
207/* Return a cli_state to a RPC pipe on the given server. Use the
208 credentials passed if not NULL. If an error occurs errstr is set to a
209 string describing the error and NULL is returned. If set, errstr must
210 be freed by calling free(). */
211
212struct cli_state *open_pipe_creds(char *server, PyObject *creds,
213 int pipe_idx, char **errstr)
214{
215 char *username, *password, *domain;
216 struct cli_state *cli;
217 struct rpc_pipe_client *pipe_hnd;
218 NTSTATUS result;
219
220 /* Extract credentials from the python dictionary */
221
222 if (!py_parse_creds(creds, &username, &domain, &password, errstr))
223 return NULL;
224
225 /* Now try to connect */
226
227 result = cli_full_connection(
228 &cli, NULL, server, NULL, 0, "IPC$", "IPC",
229 username, domain, password, 0, Undefined, NULL);
230
231 if (!NT_STATUS_IS_OK(result)) {
232 *errstr = SMB_STRDUP("error connecting to IPC$ pipe");
233 return NULL;
234 }
235
236 pipe_hnd = cli_rpc_pipe_open_noauth(cli, pipe_idx, &result);
237 if (!pipe_hnd) {
238 cli_shutdown(cli);
239 asprintf(errstr, "error opening pipe index %d", pipe_idx);
240 return NULL;
241 }
242
243 *errstr = NULL;
244
245 return cli;
246}
247
248/* Return true if a dictionary contains a "level" key with an integer
249 value. Set the value if so. */
250
251BOOL get_level_value(PyObject *dict, uint32 *level)
252{
253 PyObject *obj;
254
255 if (!(obj = PyDict_GetItemString(dict, "level")) ||
256 !PyInt_Check(obj))
257 return False;
258
259 if (level)
260 *level = PyInt_AsLong(obj);
261
262 return True;
263}
Note: See TracBrowser for help on using the repository browser.