• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.0.25b/source/python/
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}
264