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
),
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
),
39 /* Initialise samba client routines */
41 static BOOL initialised
;
43 void py_samba_init(void)
50 /* Load configuration file */
52 if (!lp_load(dyn_CONFIGFILE
, True
, False
, False
, True
))
53 fprintf(stderr
, "Can't load %s\n", dyn_CONFIGFILE
);
55 /* Misc other stuff */
63 /* Debuglevel routines */
65 PyObject
*get_debuglevel(PyObject
*self
, PyObject
*args
)
69 if (!PyArg_ParseTuple(args
, ""))
72 debuglevel
= PyInt_FromLong(DEBUGLEVEL
);
77 PyObject
*set_debuglevel(PyObject
*self
, PyObject
*args
)
81 if (!PyArg_ParseTuple(args
, "i", &debuglevel
))
84 DEBUGLEVEL
= debuglevel
;
90 /* Initialise logging */
92 PyObject
*py_setup_logging(PyObject
*self
, PyObject
*args
, PyObject
*kw
)
94 BOOL interactive
= False
;
95 char *logfilename
= NULL
;
96 static char *kwlist
[] = {"interactive", "logfilename", NULL
};
98 if (!PyArg_ParseTupleAndKeywords(
99 args
, kw
, "|is", kwlist
, &interactive
, &logfilename
))
102 if (interactive
&& logfilename
) {
103 PyErr_SetString(PyExc_RuntimeError
,
104 "can't be interactive and set log file name");
109 setup_logging("spoolss", True
);
112 lp_set_logfile(logfilename
);
113 setup_logging(logfilename
, False
);
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. */
128 BOOL
py_parse_creds(PyObject
*creds
, char **username
, char **domain
,
129 char **password
, char **errstr
)
131 /* Initialise anonymous credentials */
137 if (creds
&& PyDict_Size(creds
) > 0) {
138 PyObject
*username_obj
, *password_obj
, *domain_obj
;
139 PyObject
*key
, *value
;
142 /* Check for presence of required fields */
144 username_obj
= PyDict_GetItemString(creds
, "username");
145 domain_obj
= PyDict_GetItemString(creds
, "domain");
146 password_obj
= PyDict_GetItemString(creds
, "password");
149 *errstr
= SMB_STRDUP("no username field in credential");
154 *errstr
= SMB_STRDUP("no domain field in credential");
159 *errstr
= SMB_STRDUP("no password field in credential");
163 /* Check type of required fields */
165 if (!PyString_Check(username_obj
)) {
166 *errstr
= SMB_STRDUP("username field is not string type");
170 if (!PyString_Check(domain_obj
)) {
171 *errstr
= SMB_STRDUP("domain field is not string type");
175 if (!PyString_Check(password_obj
)) {
176 *errstr
= SMB_STRDUP("password field is not string type");
180 /* Look for any extra fields */
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) {
189 "creds contain extra field '%s'",
190 PyString_AsString(key
));
197 *username
= PyString_AsString(username_obj
);
198 *domain
= PyString_AsString(domain_obj
);
199 *password
= PyString_AsString(password_obj
);
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(). */
212 struct cli_state
*open_pipe_creds(char *server
, PyObject
*creds
,
213 int pipe_idx
, char **errstr
)
215 char *username
, *password
, *domain
;
216 struct cli_state
*cli
;
217 struct rpc_pipe_client
*pipe_hnd
;
220 /* Extract credentials from the python dictionary */
222 if (!py_parse_creds(creds
, &username
, &domain
, &password
, errstr
))
225 /* Now try to connect */
227 result
= cli_full_connection(
228 &cli
, NULL
, server
, NULL
, 0, "IPC$", "IPC",
229 username
, domain
, password
, 0, Undefined
, NULL
);
231 if (!NT_STATUS_IS_OK(result
)) {
232 *errstr
= SMB_STRDUP("error connecting to IPC$ pipe");
236 pipe_hnd
= cli_rpc_pipe_open_noauth(cli
, pipe_idx
, &result
);
239 asprintf(errstr
, "error opening pipe index %d", pipe_idx
);
248 /* Return true if a dictionary contains a "level" key with an integer
249 value. Set the value if so. */
251 BOOL
get_level_value(PyObject
*dict
, uint32
*level
)
255 if (!(obj
= PyDict_GetItemString(dict
, "level")) ||
260 *level
= PyInt_AsLong(obj
);