source: branches/samba-3.0/source/python/py_samr.c

Last change on this file was 124, checked in by Paul Smedley, 17 years ago

Update source to 3.0.28a

File size: 16.6 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_samr.h"
22
23/*
24 * Exceptions raised by this module
25 */
26
27PyObject *samr_error; /* This indicates a non-RPC related error
28 such as name lookup failure */
29
30PyObject *samr_ntstatus; /* This exception is raised when a RPC call
31 returns a status code other than
32 NT_STATUS_OK */
33
34/* SAMR group handle object */
35
36static void py_samr_group_hnd_dealloc(PyObject* self)
37{
38 PyObject_Del(self);
39}
40
41static PyMethodDef samr_group_methods[] = {
42 { NULL }
43};
44
45static PyObject *py_samr_group_hnd_getattr(PyObject *self, char *attrname)
46{
47 return Py_FindMethod(samr_group_methods, self, attrname);
48}
49
50PyTypeObject samr_group_hnd_type = {
51 PyObject_HEAD_INIT(NULL)
52 0,
53 "SAMR Group Handle",
54 sizeof(samr_group_hnd_object),
55 0,
56 py_samr_group_hnd_dealloc, /*tp_dealloc*/
57 0, /*tp_print*/
58 py_samr_group_hnd_getattr, /*tp_getattr*/
59 0, /*tp_setattr*/
60 0, /*tp_compare*/
61 0, /*tp_repr*/
62 0, /*tp_as_number*/
63 0, /*tp_as_sequence*/
64 0, /*tp_as_mapping*/
65 0, /*tp_hash */
66};
67
68PyObject *new_samr_group_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
69 POLICY_HND *pol)
70{
71 samr_group_hnd_object *o;
72
73 o = PyObject_New(samr_group_hnd_object, &samr_group_hnd_type);
74
75 o->cli = cli;
76 o->mem_ctx = mem_ctx;
77 memcpy(&o->group_pol, pol, sizeof(POLICY_HND));
78
79 return (PyObject*)o;
80}
81
82/* Alias handle object */
83
84static void py_samr_alias_hnd_dealloc(PyObject* self)
85{
86 PyObject_Del(self);
87}
88
89static PyMethodDef samr_alias_methods[] = {
90 { NULL }
91};
92
93static PyObject *py_samr_alias_hnd_getattr(PyObject *self, char *attrname)
94{
95 return Py_FindMethod(samr_alias_methods, self, attrname);
96}
97
98PyTypeObject samr_alias_hnd_type = {
99 PyObject_HEAD_INIT(NULL)
100 0,
101 "SAMR Alias Handle",
102 sizeof(samr_alias_hnd_object),
103 0,
104 py_samr_alias_hnd_dealloc, /*tp_dealloc*/
105 0, /*tp_print*/
106 py_samr_alias_hnd_getattr, /*tp_getattr*/
107 0, /*tp_setattr*/
108 0, /*tp_compare*/
109 0, /*tp_repr*/
110 0, /*tp_as_number*/
111 0, /*tp_as_sequence*/
112 0, /*tp_as_mapping*/
113 0, /*tp_hash */
114};
115
116PyObject *new_samr_alias_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
117 POLICY_HND *pol)
118{
119 samr_alias_hnd_object *o;
120
121 o = PyObject_New(samr_alias_hnd_object, &samr_alias_hnd_type);
122
123 o->cli = cli;
124 o->mem_ctx = mem_ctx;
125 memcpy(&o->alias_pol, pol, sizeof(POLICY_HND));
126
127 return (PyObject*)o;
128}
129
130/* SAMR user handle object */
131
132static void py_samr_user_hnd_dealloc(PyObject* self)
133{
134 PyObject_Del(self);
135}
136
137static PyObject *samr_set_user_info2(PyObject *self, PyObject *args,
138 PyObject *kw)
139{
140 samr_user_hnd_object *user_hnd = (samr_user_hnd_object *)self;
141 static char *kwlist[] = { "dict", NULL };
142 PyObject *info, *result = NULL;
143 SAM_USERINFO_CTR ctr;
144 TALLOC_CTX *mem_ctx;
145 uchar sess_key[16];
146 NTSTATUS ntstatus;
147 int level;
148 union {
149 SAM_USER_INFO_16 id16;
150 SAM_USER_INFO_21 id21;
151 } pinfo;
152
153 if (!PyArg_ParseTupleAndKeywords(
154 args, kw, "O!", kwlist, &PyDict_Type, &info))
155 return NULL;
156
157 if (!get_level_value(info, &level)) {
158 PyErr_SetString(samr_error, "invalid info level");
159 return NULL;
160 }
161
162 ZERO_STRUCT(ctr);
163
164 ctr.switch_value = level;
165
166 switch(level) {
167 case 16:
168 ctr.info.id16 = &pinfo.id16;
169
170 if (!py_to_SAM_USER_INFO_16(ctr.info.id16, info)) {
171 PyErr_SetString(
172 samr_error, "error converting user info");
173 goto done;
174 }
175
176 break;
177 case 21:
178 ctr.info.id21 = &pinfo.id21;
179
180 if (!py_to_SAM_USER_INFO_21(ctr.info.id21, info)) {
181 PyErr_SetString(
182 samr_error, "error converting user info");
183 goto done;
184 }
185
186 break;
187 default:
188 PyErr_SetString(samr_error, "unsupported info level");
189 goto done;
190 }
191
192 /* Call RPC function */
193
194 if (!(mem_ctx = talloc_init("samr_set_user_info2"))) {
195 PyErr_SetString(
196 samr_error, "unable to init talloc context\n");
197 goto done;
198 }
199
200 ntstatus = rpccli_samr_set_userinfo2(
201 user_hnd->cli, mem_ctx, &user_hnd->user_pol, level,
202 sess_key, &ctr);
203
204 talloc_destroy(mem_ctx);
205
206 if (!NT_STATUS_IS_OK(ntstatus)) {
207 PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
208 goto done;
209 }
210
211 Py_INCREF(Py_None);
212 result = Py_None;
213
214done:
215 return result;
216}
217
218static PyObject *samr_delete_dom_user(PyObject *self, PyObject *args,
219 PyObject *kw)
220{
221 samr_user_hnd_object *user_hnd = (samr_user_hnd_object *)self;
222 static char *kwlist[] = { NULL };
223 NTSTATUS ntstatus;
224 TALLOC_CTX *mem_ctx;
225 PyObject *result = NULL;
226
227 if (!PyArg_ParseTupleAndKeywords(
228 args, kw, "", kwlist))
229 return NULL;
230
231 if (!(mem_ctx = talloc_init("samr_delete_dom_user"))) {
232 PyErr_SetString(samr_error, "unable to init talloc context");
233 return NULL;
234 }
235
236 ntstatus = rpccli_samr_delete_dom_user(
237 user_hnd->cli, mem_ctx, &user_hnd->user_pol);
238
239 if (!NT_STATUS_IS_OK(ntstatus)) {
240 PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
241 goto done;
242 }
243
244 Py_INCREF(Py_None);
245 result = Py_None;
246
247done:
248 talloc_destroy(mem_ctx);
249
250 return result;
251}
252
253static PyMethodDef samr_user_methods[] = {
254 { "delete_domain_user", (PyCFunction)samr_delete_dom_user,
255 METH_VARARGS | METH_KEYWORDS,
256 "Delete domain user." },
257 { "set_user_info2", (PyCFunction)samr_set_user_info2,
258 METH_VARARGS | METH_KEYWORDS,
259 "Set user info 2" },
260 { NULL }
261};
262
263static PyObject *py_samr_user_hnd_getattr(PyObject *self, char *attrname)
264{
265 return Py_FindMethod(samr_user_methods, self, attrname);
266}
267
268PyTypeObject samr_user_hnd_type = {
269 PyObject_HEAD_INIT(NULL)
270 0,
271 "SAMR User Handle",
272 sizeof(samr_user_hnd_object),
273 0,
274 py_samr_user_hnd_dealloc, /*tp_dealloc*/
275 0, /*tp_print*/
276 py_samr_user_hnd_getattr, /*tp_getattr*/
277 0, /*tp_setattr*/
278 0, /*tp_compare*/
279 0, /*tp_repr*/
280 0, /*tp_as_number*/
281 0, /*tp_as_sequence*/
282 0, /*tp_as_mapping*/
283 0, /*tp_hash */
284};
285
286PyObject *new_samr_user_hnd_object(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
287 POLICY_HND *pol)
288{
289 samr_user_hnd_object *o;
290
291 o = PyObject_New(samr_user_hnd_object, &samr_user_hnd_type);
292
293 o->cli = cli;
294 o->mem_ctx = mem_ctx;
295 memcpy(&o->user_pol, pol, sizeof(POLICY_HND));
296
297 return (PyObject*)o;
298}
299
300/* SAMR connect handle object */
301
302static void py_samr_connect_hnd_dealloc(PyObject* self)
303{
304 PyObject_Del(self);
305}
306
307PyObject *new_samr_domain_hnd_object(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
308 POLICY_HND *pol)
309{
310 samr_domain_hnd_object *o;
311
312 o = PyObject_New(samr_domain_hnd_object, &samr_domain_hnd_type);
313
314 o->cli = cli;
315 o->mem_ctx = mem_ctx;
316 memcpy(&o->domain_pol, pol, sizeof(POLICY_HND));
317
318 return (PyObject*)o;
319}
320
321static PyObject *samr_open_domain(PyObject *self, PyObject *args, PyObject *kw)
322{
323 samr_connect_hnd_object *connect_hnd = (samr_connect_hnd_object *)self;
324 static char *kwlist[] = { "sid", "access", NULL };
325 uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
326 char *sid_str;
327 DOM_SID sid;
328 TALLOC_CTX *mem_ctx = NULL;
329 POLICY_HND domain_pol;
330 NTSTATUS ntstatus;
331 PyObject *result = NULL;
332
333 if (!PyArg_ParseTupleAndKeywords(
334 args, kw, "s|i", kwlist, &sid_str, &desired_access))
335 return NULL;
336
337 if (!string_to_sid(&sid, sid_str)) {
338 PyErr_SetString(PyExc_TypeError, "string is not a sid");
339 return NULL;
340 }
341
342 if (!(mem_ctx = talloc_init("samr_open_domain"))) {
343 PyErr_SetString(samr_error, "unable to init talloc context");
344 return NULL;
345 }
346
347 ntstatus = rpccli_samr_open_domain(
348 connect_hnd->cli, mem_ctx, &connect_hnd->connect_pol,
349 desired_access, &sid, &domain_pol);
350
351 if (!NT_STATUS_IS_OK(ntstatus)) {
352 PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
353 goto done;
354 }
355
356 result = new_samr_domain_hnd_object(
357 connect_hnd->cli, mem_ctx, &domain_pol);
358
359done:
360 if (!result) {
361 if (mem_ctx)
362 talloc_destroy(mem_ctx);
363 }
364
365 return result;
366}
367
368static PyMethodDef samr_connect_methods[] = {
369 { "open_domain", (PyCFunction)samr_open_domain,
370 METH_VARARGS | METH_KEYWORDS,
371 "Open a handle on a domain" },
372
373 { NULL }
374};
375
376static PyObject *py_samr_connect_hnd_getattr(PyObject *self, char *attrname)
377{
378 return Py_FindMethod(samr_connect_methods, self, attrname);
379}
380
381PyTypeObject samr_connect_hnd_type = {
382 PyObject_HEAD_INIT(NULL)
383 0,
384 "SAMR Connect Handle",
385 sizeof(samr_connect_hnd_object),
386 0,
387 py_samr_connect_hnd_dealloc, /*tp_dealloc*/
388 0, /*tp_print*/
389 py_samr_connect_hnd_getattr, /*tp_getattr*/
390 0, /*tp_setattr*/
391 0, /*tp_compare*/
392 0, /*tp_repr*/
393 0, /*tp_as_number*/
394 0, /*tp_as_sequence*/
395 0, /*tp_as_mapping*/
396 0, /*tp_hash */
397};
398
399PyObject *new_samr_connect_hnd_object(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
400 POLICY_HND *pol)
401{
402 samr_connect_hnd_object *o;
403
404 o = PyObject_New(samr_connect_hnd_object, &samr_connect_hnd_type);
405
406 o->cli = cli;
407 o->mem_ctx = mem_ctx;
408 memcpy(&o->connect_pol, pol, sizeof(POLICY_HND));
409
410 return (PyObject*)o;
411}
412
413/* SAMR domain handle object */
414
415static void py_samr_domain_hnd_dealloc(PyObject* self)
416{
417 PyObject_Del(self);
418}
419
420static PyObject *samr_enum_dom_groups(PyObject *self, PyObject *args,
421 PyObject *kw)
422{
423 samr_domain_hnd_object *domain_hnd = (samr_domain_hnd_object *)self;
424 static char *kwlist[] = { NULL };
425 TALLOC_CTX *mem_ctx;
426/* uint32 desired_access = MAXIMUM_ALLOWED_ACCESS; */
427 uint32 start_idx, size, num_dom_groups;
428 struct acct_info *dom_groups;
429 NTSTATUS result;
430 PyObject *py_result = NULL;
431
432 if (!PyArg_ParseTupleAndKeywords(args, kw, "", kwlist))
433 return NULL;
434
435 if (!(mem_ctx = talloc_init("samr_enum_dom_groups"))) {
436 PyErr_SetString(samr_error, "unable to init talloc context");
437 return NULL;
438 }
439
440 start_idx = 0;
441 size = 0xffff;
442
443 do {
444 result = rpccli_samr_enum_dom_groups(
445 domain_hnd->cli, mem_ctx, &domain_hnd->domain_pol,
446 &start_idx, size, &dom_groups, &num_dom_groups);
447
448 if (NT_STATUS_IS_OK(result) ||
449 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
450 py_from_acct_info(&py_result, dom_groups,
451 num_dom_groups);
452 }
453
454 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
455
456 return py_result;
457}
458
459static PyObject *samr_create_dom_user(PyObject *self, PyObject *args,
460 PyObject *kw)
461{
462 samr_domain_hnd_object *domain_hnd = (samr_domain_hnd_object *)self;
463 static char *kwlist[] = { "account_name", "acb_info", NULL };
464 char *account_name;
465 NTSTATUS ntstatus;
466 uint32 acct_flags = 0;
467 uint32 user_rid;
468 PyObject *result = NULL;
469 TALLOC_CTX *mem_ctx;
470 uint32 acb_info = ACB_NORMAL;
471 POLICY_HND user_pol;
472
473 if (!PyArg_ParseTupleAndKeywords(
474 args, kw, "s|i", kwlist, &account_name, &acb_info))
475 return NULL;
476
477 if (!(mem_ctx = talloc_init("samr_create_dom_user"))) {
478 PyErr_SetString(samr_error, "unable to init talloc context");
479 return NULL;
480 }
481
482 acct_flags = SAMR_GENERIC_READ | SAMR_GENERIC_WRITE |
483 SAMR_GENERIC_EXECUTE | SAMR_STANDARD_WRITEDAC |
484 SAMR_STANDARD_DELETE | SAMR_USER_SETPASS | SAMR_USER_GETATTR |
485 SAMR_USER_SETATTR;
486 DEBUG(10, ("Creating account with flags: %d\n",acct_flags));
487 ntstatus = rpccli_samr_create_dom_user(
488 domain_hnd->cli, mem_ctx, &domain_hnd->domain_pol,
489 account_name, acb_info, acct_flags, &user_pol, &user_rid);
490
491 if (!NT_STATUS_IS_OK(ntstatus)) {
492 PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
493 talloc_destroy(mem_ctx);
494 goto done;
495 }
496
497 result = new_samr_user_hnd_object(
498 domain_hnd->cli, mem_ctx, &user_pol);
499
500done:
501
502 return result;
503}
504
505static PyMethodDef samr_domain_methods[] = {
506 { "enum_domain_groups", (PyCFunction)samr_enum_dom_groups,
507 METH_VARARGS | METH_KEYWORDS, "Enumerate domain groups" },
508 { "create_domain_user", (PyCFunction)samr_create_dom_user,
509 METH_VARARGS | METH_KEYWORDS, "Create domain user" },
510 { NULL }
511};
512
513static PyObject *py_samr_domain_hnd_getattr(PyObject *self, char *attrname)
514{
515 return Py_FindMethod(samr_domain_methods, self, attrname);
516}
517
518PyTypeObject samr_domain_hnd_type = {
519 PyObject_HEAD_INIT(NULL)
520 0,
521 "SAMR Domain Handle",
522 sizeof(samr_domain_hnd_object),
523 0,
524 py_samr_domain_hnd_dealloc, /*tp_dealloc*/
525 0, /*tp_print*/
526 py_samr_domain_hnd_getattr, /*tp_getattr*/
527 0, /*tp_setattr*/
528 0, /*tp_compare*/
529 0, /*tp_repr*/
530 0, /*tp_as_number*/
531 0, /*tp_as_sequence*/
532 0, /*tp_as_mapping*/
533 0, /*tp_hash */
534};
535
536static PyObject *samr_connect(PyObject *self, PyObject *args, PyObject *kw)
537{
538 static char *kwlist[] = { "server", "creds", "access", NULL };
539 uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
540 char *server, *errstr;
541 struct cli_state *cli = NULL;
542 POLICY_HND hnd;
543 TALLOC_CTX *mem_ctx = NULL;
544 PyObject *result = NULL, *creds = NULL;
545 NTSTATUS ntstatus;
546
547 if (!PyArg_ParseTupleAndKeywords(
548 args, kw, "s|Oi", kwlist, &server, &creds,
549 &desired_access))
550 return NULL;
551
552 if (server[0] != '\\' || server[1] != '\\') {
553 PyErr_SetString(PyExc_ValueError, "UNC name required");
554 return NULL;
555 }
556
557 server += 2;
558
559 if (creds && creds != Py_None && !PyDict_Check(creds)) {
560 PyErr_SetString(PyExc_TypeError,
561 "credentials must be dictionary or None");
562 return NULL;
563 }
564
565 if (!(cli = open_pipe_creds(server, creds, PI_SAMR, &errstr))) {
566 PyErr_SetString(samr_error, errstr);
567 free(errstr);
568 return NULL;
569 }
570
571 if (!(mem_ctx = talloc_init("samr_connect"))) {
572 PyErr_SetString(samr_ntstatus,
573 "unable to init talloc context\n");
574 goto done;
575 }
576
577 ntstatus = rpccli_samr_connect(cli->pipe_list, mem_ctx, desired_access, &hnd);
578
579 if (!NT_STATUS_IS_OK(ntstatus)) {
580 cli_shutdown(cli);
581 PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
582 goto done;
583 }
584
585 result = new_samr_connect_hnd_object(cli->pipe_list, mem_ctx, &hnd);
586
587done:
588 if (!result) {
589 if (cli)
590 cli_shutdown(cli);
591
592 if (mem_ctx)
593 talloc_destroy(mem_ctx);
594 }
595
596 return result;
597}
598
599/*
600 * Module initialisation
601 */
602
603static PyMethodDef samr_methods[] = {
604
605 /* Open/close samr connect handles */
606
607 { "connect", (PyCFunction)samr_connect,
608 METH_VARARGS | METH_KEYWORDS,
609 "Open a connect handle" },
610
611 { NULL }
612};
613
614static struct const_vals {
615 char *name;
616 uint32 value;
617} module_const_vals[] = {
618
619 /* Account control bits */
620
621 { "ACB_DISABLED", 0x0001 },
622 { "ACB_HOMDIRREQ", 0x0002 },
623 { "ACB_PWNOTREQ", 0x0004 },
624 { "ACB_TEMPDUP", 0x0008 },
625 { "ACB_NORMAL", 0x0010 },
626 { "ACB_MNS", 0x0020 },
627 { "ACB_DOMTRUST", 0x0040 },
628 { "ACB_WSTRUST", 0x0080 },
629 { "ACB_SVRTRUST", 0x0100 },
630 { "ACB_PWNOEXP", 0x0200 },
631 { "ACB_AUTOLOCK", 0x0400 },
632
633 { NULL }
634};
635
636static void const_init(PyObject *dict)
637{
638 struct const_vals *tmp;
639 PyObject *obj;
640
641 for (tmp = module_const_vals; tmp->name; tmp++) {
642 obj = PyInt_FromLong(tmp->value);
643 PyDict_SetItemString(dict, tmp->name, obj);
644 Py_DECREF(obj);
645 }
646}
647
648void initsamr(void)
649{
650 PyObject *module, *dict;
651
652 /* Initialise module */
653
654 module = Py_InitModule("samr", samr_methods);
655 dict = PyModule_GetDict(module);
656
657 samr_error = PyErr_NewException("samr.error", NULL, NULL);
658 PyDict_SetItemString(dict, "error", samr_error);
659
660 samr_ntstatus = PyErr_NewException("samr.ntstatus", NULL, NULL);
661 PyDict_SetItemString(dict, "ntstatus", samr_ntstatus);
662
663 /* Initialise policy handle object */
664
665 samr_connect_hnd_type.ob_type = &PyType_Type;
666 samr_domain_hnd_type.ob_type = &PyType_Type;
667 samr_user_hnd_type.ob_type = &PyType_Type;
668 samr_group_hnd_type.ob_type = &PyType_Type;
669 samr_alias_hnd_type.ob_type = &PyType_Type;
670
671 /* Initialise constants */
672
673 const_init(dict);
674
675 /* Do samba initialisation */
676
677 py_samba_init();
678
679 setup_logging("samr", True);
680 DEBUGLEVEL = 10;
681}
Note: See TracBrowser for help on using the repository browser.