s3-passdb: Fix string duplication to pointers.
[sfrench/samba-autobuild/.git] / source3 / passdb / py_passdb.c
1 /*
2    Python interface to passdb
3
4    Copyright (C) Amitay Isaacs 2011
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 3 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, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <Python.h>
21 #include <pytalloc.h>
22 #include "includes.h"
23 #include "lib/util/talloc_stack.h"
24 #include "libcli/security/security.h"
25 #include "librpc/gen_ndr/idmap.h"
26 #include "passdb.h"
27 #include "secrets.h"
28
29 /* There's no Py_ssize_t in 2.4, apparently */
30 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
31 typedef int Py_ssize_t;
32 typedef inquiry lenfunc;
33 typedef intargfunc ssizeargfunc;
34 #endif
35
36 #ifndef Py_TYPE /* Py_TYPE is only available on Python > 2.6 */
37 #define Py_TYPE(ob)             (((PyObject*)(ob))->ob_type)
38 #endif
39
40 #ifndef PY_CHECK_TYPE
41 #define PY_CHECK_TYPE(type, var, fail) \
42         if (!PyObject_TypeCheck(var, type)) {\
43                 PyErr_Format(PyExc_TypeError, __location__ ": Expected type '%s' for '%s' of type '%s'", (type)->tp_name, #var, Py_TYPE(var)->tp_name); \
44                 fail; \
45         }
46 #endif
47
48
49 static PyTypeObject *dom_sid_Type = NULL;
50 static PyTypeObject *security_Type = NULL;
51 static PyTypeObject *guid_Type = NULL;
52
53 staticforward PyTypeObject PySamu;
54 staticforward PyTypeObject PyGroupmap;
55 staticforward PyTypeObject PyPDB;
56
57 static PyObject *py_pdb_error;
58
59 void initpassdb(void);
60
61
62 /************************** PIDL Autogeneratd ******************************/
63
64 static PyObject *py_samu_get_logon_time(PyObject *obj, void *closure)
65 {
66         TALLOC_CTX *frame = talloc_stackframe();
67         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
68         PyObject *py_logon_time;
69
70         py_logon_time = PyInt_FromLong(pdb_get_logon_time(sam_acct));
71         talloc_free(frame);
72         return py_logon_time;
73 }
74
75 static int py_samu_set_logon_time(PyObject *obj, PyObject *value, void *closure)
76 {
77         TALLOC_CTX *frame = talloc_stackframe();
78         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
79
80         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
81         if (!pdb_set_logon_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
82                 talloc_free(frame);
83                 return -1;
84         }
85         talloc_free(frame);
86         return 0;
87 }
88
89 static PyObject *py_samu_get_logoff_time(PyObject *obj, void *closure)
90 {
91         TALLOC_CTX *frame = talloc_stackframe();
92         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
93         PyObject *py_logoff_time;
94
95         py_logoff_time = PyInt_FromLong(pdb_get_logoff_time(sam_acct));
96         talloc_free(frame);
97         return py_logoff_time;
98 }
99
100 static int py_samu_set_logoff_time(PyObject *obj, PyObject *value, void *closure)
101 {
102         TALLOC_CTX *frame = talloc_stackframe();
103         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
104
105         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
106         if (!pdb_set_logoff_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
107                 talloc_free(frame);
108                 return -1;
109         }
110         talloc_free(frame);
111         return 0;
112 }
113
114 static PyObject *py_samu_get_kickoff_time(PyObject *obj, void *closure)
115 {
116         TALLOC_CTX *frame = talloc_stackframe();
117         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
118         PyObject *py_kickoff_time;
119
120         py_kickoff_time = PyInt_FromLong(pdb_get_kickoff_time(sam_acct));
121         talloc_free(frame);
122         return py_kickoff_time;
123 }
124
125 static int py_samu_set_kickoff_time(PyObject *obj, PyObject *value, void *closure)
126 {
127         TALLOC_CTX *frame = talloc_stackframe();
128         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
129
130         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
131         if (!pdb_set_kickoff_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
132                 talloc_free(frame);
133                 return -1;
134         }
135         talloc_free(frame);
136         return 0;
137 }
138
139 static PyObject *py_samu_get_bad_password_time(PyObject *obj, void *closure)
140 {
141         TALLOC_CTX *frame = talloc_stackframe();
142         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
143         PyObject *py_bad_password_time;
144
145         py_bad_password_time = PyInt_FromLong(pdb_get_bad_password_time(sam_acct));
146         talloc_free(frame);
147         return py_bad_password_time;
148 }
149
150 static int py_samu_set_bad_password_time(PyObject *obj, PyObject *value, void *closure)
151 {
152         TALLOC_CTX *frame = talloc_stackframe();
153         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
154
155         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
156         if (!pdb_set_bad_password_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
157                 talloc_free(frame);
158                 return -1;
159         }
160         talloc_free(frame);
161         return 0;
162 }
163
164 static PyObject *py_samu_get_pass_last_set_time(PyObject *obj, void *closure)
165 {
166         TALLOC_CTX *frame = talloc_stackframe();
167         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
168         PyObject *py_pass_last_set_time;
169
170         py_pass_last_set_time = PyInt_FromLong(pdb_get_pass_last_set_time(sam_acct));
171         talloc_free(frame);
172         return py_pass_last_set_time;
173 }
174
175 static int py_samu_set_pass_last_set_time(PyObject *obj, PyObject *value, void *closure)
176 {
177         TALLOC_CTX *frame = talloc_stackframe();
178         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
179
180         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
181         if (!pdb_set_pass_last_set_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
182                 talloc_free(frame);
183                 return -1;
184         }
185         talloc_free(frame);
186         return 0;
187 }
188
189 static PyObject *py_samu_get_pass_can_change_time(PyObject *obj, void *closure)
190 {
191         TALLOC_CTX *frame = talloc_stackframe();
192         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
193         PyObject *py_pass_can_change_time;
194
195         py_pass_can_change_time = PyInt_FromLong(pdb_get_pass_can_change_time(sam_acct));
196         talloc_free(frame);
197         return py_pass_can_change_time;
198 }
199
200 static int py_samu_set_pass_can_change_time(PyObject *obj, PyObject *value, void *closure)
201 {
202         TALLOC_CTX *frame = talloc_stackframe();
203         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
204
205         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
206         if (!pdb_set_pass_can_change_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
207                 talloc_free(frame);
208                 return -1;
209         }
210         talloc_free(frame);
211         return 0;
212 }
213
214 static PyObject *py_samu_get_pass_must_change_time(PyObject *obj, void *closure)
215 {
216         TALLOC_CTX *frame = talloc_stackframe();
217         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
218         PyObject *py_pass_must_change_time;
219
220         py_pass_must_change_time = PyInt_FromLong(pdb_get_pass_must_change_time(sam_acct));
221         talloc_free(frame);
222         return py_pass_must_change_time;
223 }
224
225 static int py_samu_set_pass_must_change_time(PyObject *obj, PyObject *value, void *closure)
226 {
227         TALLOC_CTX *frame = talloc_stackframe();
228         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
229
230         /* TODO: make this not a get/set or give a better exception */
231         talloc_free(frame);
232         return -1;
233 }
234
235 static PyObject *py_samu_get_username(PyObject *obj, void *closure)
236 {
237         TALLOC_CTX *frame = talloc_stackframe();
238         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
239         PyObject *py_username;
240         const char *username;
241
242         username = pdb_get_username(sam_acct);
243         if (username == NULL) {
244                 Py_RETURN_NONE;
245         }
246
247         py_username = PyString_FromString(username);
248         talloc_free(frame);
249         return py_username;
250 }
251
252 static int py_samu_set_username(PyObject *obj, PyObject *value, void *closure)
253 {
254         TALLOC_CTX *frame = talloc_stackframe();
255         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
256
257         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
258         if (!pdb_set_username(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
259                 talloc_free(frame);
260                 return -1;
261         }
262         talloc_free(frame);
263         return 0;
264 }
265
266 static PyObject *py_samu_get_domain(PyObject *obj, void *closure)
267 {
268         TALLOC_CTX *frame = talloc_stackframe();
269         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
270         PyObject *py_domain;
271         const char *domain;
272
273         domain = pdb_get_domain(sam_acct);
274         if (domain == NULL) {
275                 Py_RETURN_NONE;
276         }
277
278         py_domain = PyString_FromString(domain);
279         talloc_free(frame);
280         return py_domain;
281 }
282
283 static int py_samu_set_domain(PyObject *obj, PyObject *value, void *closure)
284 {
285         TALLOC_CTX *frame = talloc_stackframe();
286         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
287
288         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
289         if (!pdb_set_domain(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
290                 talloc_free(frame);
291                 return -1;
292         }
293         talloc_free(frame);
294         return 0;
295 }
296
297 static PyObject *py_samu_get_nt_username(PyObject *obj, void *closure)
298 {
299         TALLOC_CTX *frame = talloc_stackframe();
300         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
301         PyObject *py_nt_username;
302         const char *nt_username;
303
304         nt_username = pdb_get_nt_username(sam_acct);
305         if (nt_username == NULL) {
306                 Py_RETURN_NONE;
307         }
308
309         py_nt_username = PyString_FromString(nt_username);
310         talloc_free(frame);
311         return py_nt_username;
312 }
313
314 static int py_samu_set_nt_username(PyObject *obj, PyObject *value, void *closure)
315 {
316         TALLOC_CTX *frame = talloc_stackframe();
317         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
318
319         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
320         if (!pdb_set_nt_username(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
321                 talloc_free(frame);
322                 return -1;
323         }
324         talloc_free(frame);
325         return 0;
326 }
327
328 static PyObject *py_samu_get_full_name(PyObject *obj, void *closure)
329 {
330         TALLOC_CTX *frame = talloc_stackframe();
331         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
332         PyObject *py_full_name;
333         const char *full_name;
334
335         full_name = pdb_get_fullname(sam_acct);
336         if (full_name == NULL) {
337                 Py_RETURN_NONE;
338         }
339
340         py_full_name = PyString_FromString(full_name);
341         talloc_free(frame);
342         return py_full_name;
343 }
344
345 static int py_samu_set_full_name(PyObject *obj, PyObject *value, void *closure)
346 {
347         TALLOC_CTX *frame = talloc_stackframe();
348         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
349
350         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
351         if (!pdb_set_fullname(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
352                 talloc_free(frame);
353                 return -1;
354         }
355         talloc_free(frame);
356         return 0;
357 }
358
359 static PyObject *py_samu_get_home_dir(PyObject *obj, void *closure)
360 {
361         TALLOC_CTX *frame = talloc_stackframe();
362         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
363         PyObject *py_home_dir;
364         const char *home_dir;
365
366         home_dir = pdb_get_homedir(sam_acct);
367         if (home_dir == NULL) {
368                 Py_RETURN_NONE;
369         }
370
371         py_home_dir = PyString_FromString(home_dir);
372         talloc_free(frame);
373         return py_home_dir;
374 }
375
376 static int py_samu_set_home_dir(PyObject *obj, PyObject *value, void *closure)
377 {
378         TALLOC_CTX *frame = talloc_stackframe();
379         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
380
381         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
382         if (!pdb_set_homedir(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
383                 talloc_free(frame);
384                 return -1;
385         }
386         talloc_free(frame);
387         return 0;
388 }
389
390 static PyObject *py_samu_get_dir_drive(PyObject *obj, void *closure)
391 {
392         TALLOC_CTX *frame = talloc_stackframe();
393         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
394         PyObject *py_dir_drive;
395         const char *dir_drive;
396
397         dir_drive = pdb_get_dir_drive(sam_acct);
398         if (dir_drive == NULL) {
399                 Py_RETURN_NONE;
400         }
401
402         py_dir_drive = PyString_FromString(dir_drive);
403         talloc_free(frame);
404         return py_dir_drive;
405 }
406
407 static int py_samu_set_dir_drive(PyObject *obj, PyObject *value, void *closure)
408 {
409         TALLOC_CTX *frame = talloc_stackframe();
410         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
411
412         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
413         if (!pdb_set_dir_drive(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
414                 talloc_free(frame);
415                 return -1;
416         }
417         talloc_free(frame);
418         return 0;
419 }
420
421 static PyObject *py_samu_get_logon_script(PyObject *obj, void *closure)
422 {
423         TALLOC_CTX *frame = talloc_stackframe();
424         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
425         PyObject *py_logon_script;
426         const char *logon_script;
427
428         logon_script = pdb_get_logon_script(sam_acct);
429         if (logon_script == NULL) {
430                 Py_RETURN_NONE;
431         }
432
433         py_logon_script = PyString_FromString(logon_script);
434         talloc_free(frame);
435         return py_logon_script;
436 }
437
438 static int py_samu_set_logon_script(PyObject *obj, PyObject *value, void *closure)
439 {
440         TALLOC_CTX *frame = talloc_stackframe();
441         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
442
443         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
444         if (!pdb_set_logon_script(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
445                 talloc_free(frame);
446                 return -1;
447         }
448         talloc_free(frame);
449         return 0;
450 }
451
452 static PyObject *py_samu_get_profile_path(PyObject *obj, void *closure)
453 {
454         TALLOC_CTX *frame = talloc_stackframe();
455         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
456         PyObject *py_profile_path;
457         const char *profile_path;
458
459         profile_path = pdb_get_profile_path(sam_acct);
460         if (profile_path == NULL) {
461                 Py_RETURN_NONE;
462         }
463
464         py_profile_path = PyString_FromString(profile_path);
465         talloc_free(frame);
466         return py_profile_path;
467 }
468
469 static int py_samu_set_profile_path(PyObject *obj, PyObject *value, void *closure)
470 {
471         TALLOC_CTX *frame = talloc_stackframe();
472         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
473
474         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
475         if (!pdb_set_profile_path(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
476                 talloc_free(frame);
477                 return -1;
478         }
479         talloc_free(frame);
480         return 0;
481 }
482
483 static PyObject *py_samu_get_acct_desc(PyObject *obj, void *closure)
484 {
485         TALLOC_CTX *frame = talloc_stackframe();
486         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
487         PyObject *py_acct_desc;
488         const char *acct_desc;
489
490         acct_desc = pdb_get_acct_desc(sam_acct);
491         if (acct_desc == NULL) {
492                 Py_RETURN_NONE;
493         }
494
495         py_acct_desc = PyString_FromString(acct_desc);
496         talloc_free(frame);
497         return py_acct_desc;
498 }
499
500 static int py_samu_set_acct_desc(PyObject *obj, PyObject *value, void *closure)
501 {
502         TALLOC_CTX *frame = talloc_stackframe();
503         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
504
505         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
506         if (!pdb_set_acct_desc(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
507                 talloc_free(frame);
508                 return -1;
509         }
510         talloc_free(frame);
511         return 0;
512 }
513
514 static PyObject *py_samu_get_workstations(PyObject *obj, void *closure)
515 {
516         TALLOC_CTX *frame = talloc_stackframe();
517         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
518         PyObject *py_workstations;
519         const char *workstations;
520
521         workstations = pdb_get_workstations(sam_acct);
522         if (workstations == NULL) {
523                 Py_RETURN_NONE;
524         }
525
526         py_workstations = PyString_FromString(workstations);
527         talloc_free(frame);
528         return py_workstations;
529 }
530
531 static int py_samu_set_workstations(PyObject *obj, PyObject *value, void *closure)
532 {
533         TALLOC_CTX *frame = talloc_stackframe();
534         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
535
536         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
537         if (!pdb_set_workstations(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
538                 talloc_free(frame);
539                 return -1;
540         }
541         talloc_free(frame);
542         return 0;
543 }
544
545 static PyObject *py_samu_get_comment(PyObject *obj, void *closure)
546 {
547         TALLOC_CTX *frame = talloc_stackframe();
548         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
549         PyObject *py_comment;
550         const char *comment;
551
552         comment = pdb_get_comment(sam_acct);
553         if (comment == NULL) {
554                 Py_RETURN_NONE;
555         }
556
557         py_comment = PyString_FromString(comment);
558         talloc_free(frame);
559         return py_comment;
560 }
561
562 static int py_samu_set_comment(PyObject *obj, PyObject *value, void *closure)
563 {
564         TALLOC_CTX *frame = talloc_stackframe();
565         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
566
567         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
568         if (!pdb_set_comment(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
569                 talloc_free(frame);
570                 return -1;
571         }
572         talloc_free(frame);
573         return 0;
574 }
575
576 static PyObject *py_samu_get_munged_dial(PyObject *obj, void *closure)
577 {
578         TALLOC_CTX *frame = talloc_stackframe();
579         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
580         PyObject *py_munged_dial;
581         const char *munged_dial;
582
583         munged_dial = pdb_get_munged_dial(sam_acct);
584         if (munged_dial == NULL) {
585                 Py_RETURN_NONE;
586         }
587
588         py_munged_dial = PyString_FromString(munged_dial);
589         talloc_free(frame);
590         return py_munged_dial;
591 }
592
593 static int py_samu_set_munged_dial(PyObject *obj, PyObject *value, void *closure)
594 {
595         TALLOC_CTX *frame = talloc_stackframe();
596         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
597
598         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
599         if (!pdb_set_munged_dial(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
600                 talloc_free(frame);
601                 return -1;
602         }
603         talloc_free(frame);
604         return 0;
605 }
606
607 static PyObject *py_samu_get_user_sid(PyObject *obj, void *closure)
608 {
609         TALLOC_CTX *frame = talloc_stackframe();
610         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
611         PyObject *py_user_sid;
612         const struct dom_sid *user_sid;
613         struct dom_sid *copy_user_sid;
614         TALLOC_CTX *mem_ctx;
615
616         user_sid = pdb_get_user_sid(sam_acct);
617         if(user_sid == NULL) {
618                 Py_RETURN_NONE;
619         }
620
621         mem_ctx = talloc_new(NULL);
622         if (mem_ctx == NULL) {
623                 PyErr_NoMemory();
624                 talloc_free(frame);
625                 return NULL;
626         }
627         copy_user_sid = dom_sid_dup(mem_ctx, user_sid);
628         if (copy_user_sid == NULL) {
629                 PyErr_NoMemory();
630                 talloc_free(mem_ctx);
631                 talloc_free(frame);
632                 return NULL;
633         }
634
635         py_user_sid = pytalloc_steal(dom_sid_Type, copy_user_sid);
636
637         talloc_free(mem_ctx);
638
639         talloc_free(frame);
640         return py_user_sid;
641 }
642
643 static int py_samu_set_user_sid(PyObject *obj, PyObject *value, void *closure)
644 {
645         TALLOC_CTX *frame = talloc_stackframe();
646         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
647
648         PY_CHECK_TYPE(dom_sid_Type, value, return -1;);
649         if (!pdb_set_user_sid(sam_acct, (struct dom_sid *)pytalloc_get_ptr(value), PDB_CHANGED)) {
650                 talloc_free(frame);
651                 return -1;
652         }
653         talloc_free(frame);
654         return 0;
655 }
656
657 static PyObject *py_samu_get_group_sid(PyObject *obj, void *closure)
658 {
659         TALLOC_CTX *frame = talloc_stackframe();
660         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
661         const struct dom_sid *group_sid;
662         struct dom_sid *copy_group_sid;
663
664         group_sid = pdb_get_group_sid(sam_acct);
665         if (group_sid == NULL) {
666                 Py_RETURN_NONE;
667         }
668
669         copy_group_sid = dom_sid_dup(NULL, group_sid);
670         if (copy_group_sid == NULL) {
671                 PyErr_NoMemory();
672                 talloc_free(frame);
673                 return NULL;
674         }
675
676         talloc_free(frame);
677         return pytalloc_steal(dom_sid_Type, copy_group_sid);
678 }
679
680 static int py_samu_set_group_sid(PyObject *obj, PyObject *value, void *closure)
681 {
682         TALLOC_CTX *frame = talloc_stackframe();
683         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
684
685         PY_CHECK_TYPE(dom_sid_Type, value, return -1;);
686         if (!pdb_set_group_sid(sam_acct, (struct dom_sid *)pytalloc_get_ptr(value), PDB_CHANGED)) {
687                 talloc_free(frame);
688                 return -1;
689         }
690         talloc_free(frame);
691         return 0;
692 }
693
694 static PyObject *py_samu_get_lanman_passwd(PyObject *obj, void *closure)
695 {
696         TALLOC_CTX *frame = talloc_stackframe();
697         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
698         PyObject *py_lm_pw;
699         const char *lm_pw;
700
701         lm_pw = (const char *)pdb_get_lanman_passwd(sam_acct);
702         if (lm_pw == NULL) {
703                 Py_RETURN_NONE;
704         }
705
706         py_lm_pw = PyString_FromStringAndSize(lm_pw, LM_HASH_LEN);
707         talloc_free(frame);
708         return py_lm_pw;
709 }
710
711 static int py_samu_set_lanman_passwd(PyObject *obj, PyObject *value, void *closure)
712 {
713         TALLOC_CTX *frame = talloc_stackframe();
714         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
715
716         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
717         if (!pdb_set_lanman_passwd(sam_acct, (uint8_t *)PyString_AsString(value), PDB_CHANGED)) {
718                 talloc_free(frame);
719                 return -1;
720         }
721         talloc_free(frame);
722         return 0;
723 }
724
725 static PyObject *py_samu_get_nt_passwd(PyObject *obj, void *closure)
726 {
727         TALLOC_CTX *frame = talloc_stackframe();
728         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
729         PyObject *py_nt_pw;
730         const char *nt_pw;
731
732         nt_pw = (const char *)pdb_get_nt_passwd(sam_acct);
733         if (nt_pw == NULL) {
734                 Py_RETURN_NONE;
735         }
736
737         py_nt_pw = PyString_FromStringAndSize(nt_pw, NT_HASH_LEN);
738         talloc_free(frame);
739         return py_nt_pw;
740 }
741
742 static int py_samu_set_nt_passwd(PyObject *obj, PyObject *value, void *closure)
743 {
744         TALLOC_CTX *frame = talloc_stackframe();
745         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
746
747         if (!pdb_set_nt_passwd(sam_acct, (uint8_t *)PyString_AsString(value), PDB_CHANGED)) {
748                 talloc_free(frame);
749                 return -1;
750         }
751         talloc_free(frame);
752         return 0;
753 }
754
755 static PyObject *py_samu_get_pw_history(PyObject *obj, void *closure)
756 {
757         TALLOC_CTX *frame = talloc_stackframe();
758         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
759         PyObject *py_nt_pw_his;
760         const char *nt_pw_his;
761         uint32_t hist_len;
762
763         nt_pw_his = (const char *)pdb_get_pw_history(sam_acct, &hist_len);
764         if (nt_pw_his == NULL) {
765                 Py_RETURN_NONE;
766         }
767
768         py_nt_pw_his = PyString_FromStringAndSize(nt_pw_his, hist_len*PW_HISTORY_ENTRY_LEN);
769         talloc_free(frame);
770         return py_nt_pw_his;
771 }
772
773 static int py_samu_set_pw_history(PyObject *obj, PyObject *value, void *closure)
774 {
775         TALLOC_CTX *frame = talloc_stackframe();
776         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
777         char *nt_pw_his;
778         Py_ssize_t len;
779         uint32_t hist_len;
780
781         PyString_AsStringAndSize(value, &nt_pw_his, &len);
782         hist_len = len / PW_HISTORY_ENTRY_LEN;
783         if (!pdb_set_pw_history(sam_acct, (uint8_t *)nt_pw_his, hist_len, PDB_CHANGED)) {
784                 talloc_free(frame);
785                 return -1;
786         }
787         talloc_free(frame);
788         return 0;
789 }
790
791 static PyObject *py_samu_get_plaintext_passwd(PyObject *obj, void *closure)
792 {
793         TALLOC_CTX *frame = talloc_stackframe();
794         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
795         PyObject *py_plaintext_pw;
796         const char *plaintext_pw;
797
798         plaintext_pw = pdb_get_plaintext_passwd(sam_acct);
799         if (plaintext_pw == NULL) {
800                 Py_RETURN_NONE;
801         }
802
803         py_plaintext_pw = PyString_FromString(plaintext_pw);
804         talloc_free(frame);
805         return py_plaintext_pw;
806 }
807
808 static int py_samu_set_plaintext_passwd(PyObject *obj, PyObject *value, void *closure)
809 {
810         TALLOC_CTX *frame = talloc_stackframe();
811         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
812
813         if (!pdb_set_plaintext_passwd(sam_acct, PyString_AsString(value))) {
814                 talloc_free(frame);
815                 return -1;
816         }
817         talloc_free(frame);
818         return 0;
819 }
820
821 static PyObject *py_samu_get_acct_ctrl(PyObject *obj, void *closure)
822 {
823         TALLOC_CTX *frame = talloc_stackframe();
824         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
825         PyObject *py_acct_ctrl;
826
827         py_acct_ctrl = PyInt_FromLong(pdb_get_acct_ctrl(sam_acct));
828         talloc_free(frame);
829         return py_acct_ctrl;
830 }
831
832 static int py_samu_set_acct_ctrl(PyObject *obj, PyObject *value, void *closure)
833 {
834         TALLOC_CTX *frame = talloc_stackframe();
835         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
836
837         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
838         if (!pdb_set_acct_ctrl(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
839                 talloc_free(frame);
840                 return -1;
841         }
842         talloc_free(frame);
843         return 0;
844 }
845
846 static PyObject *py_samu_get_logon_divs(PyObject *obj, void *closure)
847 {
848         TALLOC_CTX *frame = talloc_stackframe();
849         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
850         PyObject *py_logon_divs;
851
852         py_logon_divs = PyInt_FromLong(pdb_get_logon_divs(sam_acct));
853         talloc_free(frame);
854         return py_logon_divs;
855 }
856
857 static int py_samu_set_logon_divs(PyObject *obj, PyObject *value, void *closure)
858 {
859         TALLOC_CTX *frame = talloc_stackframe();
860         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
861
862         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
863         if (!pdb_set_logon_divs(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
864                 talloc_free(frame);
865                 return -1;
866         }
867         talloc_free(frame);
868         return 0;
869 }
870
871 static PyObject *py_samu_get_hours_len(PyObject *obj, void *closure)
872 {
873         TALLOC_CTX *frame = talloc_stackframe();
874         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
875         PyObject *py_hours_len;
876
877         py_hours_len = PyInt_FromLong(pdb_get_hours_len(sam_acct));
878         talloc_free(frame);
879         return py_hours_len;
880 }
881
882 static int py_samu_set_hours_len(PyObject *obj, PyObject *value, void *closure)
883 {
884         TALLOC_CTX *frame = talloc_stackframe();
885         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
886
887         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
888         if (!pdb_set_hours_len(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
889                 talloc_free(frame);
890                 return -1;
891         }
892         talloc_free(frame);
893         return 0;
894 }
895
896 static PyObject *py_samu_get_hours(PyObject *obj, void *closure)
897 {
898         TALLOC_CTX *frame = talloc_stackframe();
899         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
900         PyObject *py_hours;
901         const char *hours;
902         int hours_len, i;
903
904         hours = (const char *)pdb_get_hours(sam_acct);
905         if(! hours) {
906                 Py_RETURN_NONE;
907         }
908
909         hours_len = pdb_get_hours_len(sam_acct);
910         if ((py_hours = PyList_New(hours_len)) == NULL) {
911                 PyErr_NoMemory();
912                 talloc_free(frame);
913                 return NULL;
914         }
915
916         for (i=0; i<hours_len; i++) {
917                 PyList_SetItem(py_hours, i, PyInt_FromLong(hours[i]));
918         }
919         talloc_free(frame);
920         return py_hours;
921 }
922
923 static int py_samu_set_hours(PyObject *obj, PyObject *value, void *closure)
924 {
925         TALLOC_CTX *frame = talloc_stackframe();
926         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
927         int i;
928         uint8_t *hours;
929         int hours_len;
930         bool status;
931
932         PY_CHECK_TYPE(&PyList_Type, value, return -1;);
933
934         hours_len = PyList_GET_SIZE(value);
935
936         hours = talloc_array(pytalloc_get_mem_ctx(obj), uint8_t, hours_len);
937         if (!hours) {
938                 PyErr_NoMemory();
939                 talloc_free(frame);
940                 return -1;
941         }
942
943         for (i=0; i < hours_len; i++) {
944                 PY_CHECK_TYPE(&PyInt_Type, PyList_GET_ITEM(value,i), return -1;);
945                 hours[i] = PyInt_AsLong(PyList_GET_ITEM(value, i));
946         }
947
948         status = pdb_set_hours(sam_acct, hours, hours_len, PDB_CHANGED);
949         talloc_free(hours);
950
951         if(! status) {
952                 talloc_free(frame);
953                 return -1;
954         }
955         talloc_free(frame);
956         return 0;
957 }
958
959 static PyObject *py_samu_get_bad_password_count(PyObject *obj, void *closure)
960 {
961         TALLOC_CTX *frame = talloc_stackframe();
962         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
963         PyObject *py_bad_password_count;
964
965         py_bad_password_count = PyInt_FromLong(pdb_get_bad_password_count(sam_acct));
966         talloc_free(frame);
967         return py_bad_password_count;
968 }
969
970 static int py_samu_set_bad_password_count(PyObject *obj, PyObject *value, void *closure)
971 {
972         TALLOC_CTX *frame = talloc_stackframe();
973         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
974
975         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
976         if (!pdb_set_bad_password_count(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
977                 talloc_free(frame);
978                 return -1;
979         }
980         talloc_free(frame);
981         return 0;
982 }
983
984 static PyObject *py_samu_get_logon_count(PyObject *obj, void *closure)
985 {
986         TALLOC_CTX *frame = talloc_stackframe();
987         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
988         PyObject *py_logon_count;
989
990         py_logon_count = PyInt_FromLong(pdb_get_logon_count(sam_acct));
991         talloc_free(frame);
992         return py_logon_count;
993 }
994
995 static int py_samu_set_logon_count(PyObject *obj, PyObject *value, void *closure)
996 {
997         TALLOC_CTX *frame = talloc_stackframe();
998         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
999
1000         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
1001         if (!pdb_set_logon_count(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
1002                 talloc_free(frame);
1003                 return -1;
1004         }
1005         talloc_free(frame);
1006         return 0;
1007 }
1008
1009 static PyObject *py_samu_get_country_code(PyObject *obj, void *closure)
1010 {
1011         TALLOC_CTX *frame = talloc_stackframe();
1012         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
1013         PyObject *py_country_code;
1014
1015         py_country_code = PyInt_FromLong(pdb_get_country_code(sam_acct));
1016         talloc_free(frame);
1017         return py_country_code;
1018 }
1019
1020 static int py_samu_set_country_code(PyObject *obj, PyObject *value, void *closure)
1021 {
1022         TALLOC_CTX *frame = talloc_stackframe();
1023         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
1024
1025         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
1026         if (!pdb_set_country_code(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
1027                 talloc_free(frame);
1028                 return -1;
1029         }
1030         talloc_free(frame);
1031         return 0;
1032 }
1033
1034 static PyObject *py_samu_get_code_page(PyObject *obj, void *closure)
1035 {
1036         TALLOC_CTX *frame = talloc_stackframe();
1037         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
1038         PyObject *py_code_page;
1039
1040         py_code_page = PyInt_FromLong(pdb_get_code_page(sam_acct));
1041         talloc_free(frame);
1042         return py_code_page;
1043 }
1044
1045 static int py_samu_set_code_page(PyObject *obj, PyObject *value, void *closure)
1046 {
1047         TALLOC_CTX *frame = talloc_stackframe();
1048         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
1049
1050         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
1051         if (!pdb_set_code_page(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
1052                 talloc_free(frame);
1053                 return -1;
1054         }
1055         talloc_free(frame);
1056         return 0;
1057 }
1058
1059 static PyGetSetDef py_samu_getsetters[] = {
1060         { discard_const_p(char, "logon_time"), py_samu_get_logon_time, py_samu_set_logon_time },
1061         { discard_const_p(char, "logoff_time"), py_samu_get_logoff_time, py_samu_set_logoff_time },
1062         { discard_const_p(char, "kickoff_time"), py_samu_get_kickoff_time, py_samu_set_kickoff_time },
1063         { discard_const_p(char, "bad_password_time"), py_samu_get_bad_password_time, py_samu_set_bad_password_time },
1064         { discard_const_p(char, "pass_last_set_time"), py_samu_get_pass_last_set_time, py_samu_set_pass_last_set_time },
1065         { discard_const_p(char, "pass_can_change_time"), py_samu_get_pass_can_change_time, py_samu_set_pass_can_change_time },
1066         { discard_const_p(char, "pass_must_change_time"), py_samu_get_pass_must_change_time, py_samu_set_pass_must_change_time },
1067         { discard_const_p(char, "username"), py_samu_get_username, py_samu_set_username },
1068         { discard_const_p(char, "domain"), py_samu_get_domain, py_samu_set_domain },
1069         { discard_const_p(char, "nt_username"), py_samu_get_nt_username, py_samu_set_nt_username },
1070         { discard_const_p(char, "full_name"), py_samu_get_full_name, py_samu_set_full_name },
1071         { discard_const_p(char, "home_dir"), py_samu_get_home_dir, py_samu_set_home_dir },
1072         { discard_const_p(char, "dir_drive"), py_samu_get_dir_drive, py_samu_set_dir_drive },
1073         { discard_const_p(char, "logon_script"), py_samu_get_logon_script, py_samu_set_logon_script },
1074         { discard_const_p(char, "profile_path"), py_samu_get_profile_path, py_samu_set_profile_path },
1075         { discard_const_p(char, "acct_desc"), py_samu_get_acct_desc, py_samu_set_acct_desc },
1076         { discard_const_p(char, "workstations"), py_samu_get_workstations, py_samu_set_workstations },
1077         { discard_const_p(char, "comment"), py_samu_get_comment, py_samu_set_comment },
1078         { discard_const_p(char, "munged_dial"), py_samu_get_munged_dial, py_samu_set_munged_dial },
1079         { discard_const_p(char, "user_sid"), py_samu_get_user_sid, py_samu_set_user_sid },
1080         { discard_const_p(char, "group_sid"), py_samu_get_group_sid, py_samu_set_group_sid },
1081         { discard_const_p(char, "lanman_passwd"), py_samu_get_lanman_passwd, py_samu_set_lanman_passwd },
1082         { discard_const_p(char, "nt_passwd"), py_samu_get_nt_passwd, py_samu_set_nt_passwd },
1083         { discard_const_p(char, "pw_history"), py_samu_get_pw_history, py_samu_set_pw_history },
1084         { discard_const_p(char, "plaintext_passwd"), py_samu_get_plaintext_passwd, py_samu_set_plaintext_passwd },
1085         { discard_const_p(char, "acct_ctrl"), py_samu_get_acct_ctrl, py_samu_set_acct_ctrl },
1086         { discard_const_p(char, "logon_divs"), py_samu_get_logon_divs, py_samu_set_logon_divs },
1087         { discard_const_p(char, "hours_len"), py_samu_get_hours_len, py_samu_set_hours_len },
1088         { discard_const_p(char, "hours"), py_samu_get_hours, py_samu_set_hours },
1089         { discard_const_p(char, "bad_password_count"), py_samu_get_bad_password_count, py_samu_set_bad_password_count },
1090         { discard_const_p(char, "logon_count"), py_samu_get_logon_count, py_samu_set_logon_count },
1091         { discard_const_p(char, "country_code"), py_samu_get_country_code, py_samu_set_country_code },
1092         { discard_const_p(char, "code_page"), py_samu_get_code_page, py_samu_set_code_page },
1093         { NULL }
1094 };
1095
1096
1097 /************************** PIDL Autogeneratd ******************************/
1098
1099 static PyObject *py_samu_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1100 {
1101         TALLOC_CTX *frame = talloc_stackframe();
1102         struct samu *sam_acct;
1103
1104         sam_acct = samu_new(NULL);
1105         if (!sam_acct) {
1106                 PyErr_NoMemory();
1107                 talloc_free(frame);
1108                 return NULL;
1109         }
1110
1111         talloc_free(frame);
1112         return pytalloc_steal(type, sam_acct);
1113 }
1114
1115 static PyTypeObject PySamu = {
1116         .tp_name = "passdb.Samu",
1117         .tp_basicsize = sizeof(pytalloc_Object),
1118         .tp_getset = py_samu_getsetters,
1119         .tp_methods = NULL,
1120         .tp_new = py_samu_new,
1121         .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
1122         .tp_doc = "Samu() -> samu object\n",
1123 };
1124
1125
1126 static PyObject *py_groupmap_get_gid(PyObject *obj, void *closure)
1127 {
1128         TALLOC_CTX *frame = talloc_stackframe();
1129         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1130         PyObject *py_gid;
1131
1132         py_gid = Py_BuildValue("i", group_map->gid);
1133         talloc_free(frame);
1134         return py_gid;
1135 }
1136
1137 static int py_groupmap_set_gid(PyObject *obj, PyObject *value, void *closure)
1138 {
1139         TALLOC_CTX *frame = talloc_stackframe();
1140         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1141
1142         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
1143         group_map->gid = PyInt_AsLong(value);
1144         talloc_free(frame);
1145         return 0;
1146 }
1147
1148 static PyObject *py_groupmap_get_sid(PyObject *obj, void *closure)
1149 {
1150         TALLOC_CTX *frame = talloc_stackframe();
1151         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1152         PyObject *py_sid;
1153         struct dom_sid *group_sid;
1154         TALLOC_CTX *mem_ctx;
1155
1156         mem_ctx = talloc_new(NULL);
1157         if (mem_ctx == NULL) {
1158                 PyErr_NoMemory();
1159                 talloc_free(frame);
1160                 return NULL;
1161         }
1162
1163         group_sid = dom_sid_dup(mem_ctx, &group_map->sid);
1164         if (group_sid == NULL) {
1165                 PyErr_NoMemory();
1166                 talloc_free(mem_ctx);
1167                 talloc_free(frame);
1168                 return NULL;
1169         }
1170
1171         py_sid = pytalloc_steal(dom_sid_Type, group_sid);
1172
1173         talloc_free(mem_ctx);
1174
1175         talloc_free(frame);
1176         return py_sid;
1177 }
1178
1179 static int py_groupmap_set_sid(PyObject *obj, PyObject *value, void *closure)
1180 {
1181         TALLOC_CTX *frame = talloc_stackframe();
1182         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1183
1184         PY_CHECK_TYPE(dom_sid_Type, value, return -1;);
1185         group_map->sid = *pytalloc_get_type(value, struct dom_sid);
1186         talloc_free(frame);
1187         return 0;
1188 }
1189
1190 static PyObject *py_groupmap_get_sid_name_use(PyObject *obj, void *closure)
1191 {
1192         TALLOC_CTX *frame = talloc_stackframe();
1193         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1194         PyObject *py_sid_name_use;
1195
1196         py_sid_name_use = PyInt_FromLong(group_map->sid_name_use);
1197         talloc_free(frame);
1198         return py_sid_name_use;
1199 }
1200
1201 static int py_groupmap_set_sid_name_use(PyObject *obj, PyObject *value, void *closure)
1202 {
1203         TALLOC_CTX *frame = talloc_stackframe();
1204         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1205
1206         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
1207         group_map->sid_name_use = PyInt_AsLong(value);
1208         talloc_free(frame);
1209         return 0;
1210 }
1211
1212 static PyObject *py_groupmap_get_nt_name(PyObject *obj, void *closure)
1213 {
1214         TALLOC_CTX *frame = talloc_stackframe();
1215         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1216         PyObject *py_nt_name;
1217         if (group_map->nt_name == NULL) {
1218                 py_nt_name = Py_None;
1219                 Py_INCREF(py_nt_name);
1220         } else {
1221                 py_nt_name = PyString_FromString(group_map->nt_name);
1222         }
1223         talloc_free(frame);
1224         return py_nt_name;
1225 }
1226
1227 static int py_groupmap_set_nt_name(PyObject *obj, PyObject *value, void *closure)
1228 {
1229         TALLOC_CTX *frame = talloc_stackframe();
1230         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1231
1232         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
1233         if (value == Py_None) {
1234                 fstrcpy(group_map->nt_name, NULL);
1235         } else {
1236                 fstrcpy(group_map->nt_name, PyString_AsString(value));
1237         }
1238         talloc_free(frame);
1239         return 0;
1240 }
1241
1242 static PyObject *py_groupmap_get_comment(PyObject *obj, void *closure)
1243 {
1244         TALLOC_CTX *frame = talloc_stackframe();
1245         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1246         PyObject *py_comment;
1247         if (group_map->comment == NULL) {
1248                 py_comment = Py_None;
1249                 Py_INCREF(py_comment);
1250         } else {
1251                 py_comment = PyString_FromString(group_map->comment);
1252         }
1253         talloc_free(frame);
1254         return py_comment;
1255 }
1256
1257 static int py_groupmap_set_comment(PyObject *obj, PyObject *value, void *closure)
1258 {
1259         TALLOC_CTX *frame = talloc_stackframe();
1260         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1261
1262         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
1263         if (value == Py_None) {
1264                 fstrcpy(group_map->comment, NULL);
1265         } else {
1266                 fstrcpy(group_map->comment, PyString_AsString(value));
1267         }
1268         talloc_free(frame);
1269         return 0;
1270 }
1271
1272 static PyGetSetDef py_groupmap_getsetters[] = {
1273         { discard_const_p(char, "gid"), py_groupmap_get_gid, py_groupmap_set_gid },
1274         { discard_const_p(char, "sid"), py_groupmap_get_sid, py_groupmap_set_sid },
1275         { discard_const_p(char, "sid_name_use"), py_groupmap_get_sid_name_use, py_groupmap_set_sid_name_use },
1276         { discard_const_p(char, "nt_name"), py_groupmap_get_nt_name, py_groupmap_set_nt_name },
1277         { discard_const_p(char, "comment"), py_groupmap_get_comment, py_groupmap_set_comment },
1278         { NULL }
1279 };
1280
1281 static PyObject *py_groupmap_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1282 {
1283         TALLOC_CTX *frame = talloc_stackframe();
1284         GROUP_MAP *group_map;
1285         TALLOC_CTX *mem_ctx;
1286         PyObject *py_group_map;
1287
1288         mem_ctx = talloc_new(NULL);
1289         if (mem_ctx == NULL) {
1290                 PyErr_NoMemory();
1291                 talloc_free(frame);
1292                 return NULL;
1293         }
1294
1295         group_map = talloc_zero(mem_ctx, GROUP_MAP);
1296         if (group_map == NULL) {
1297                 PyErr_NoMemory();
1298                 talloc_free(mem_ctx);
1299                 talloc_free(frame);
1300                 return NULL;
1301         }
1302
1303         py_group_map = pytalloc_steal(type, group_map);
1304         if (py_group_map == NULL) {
1305                 PyErr_NoMemory();
1306                 talloc_free(mem_ctx);
1307                 talloc_free(frame);
1308                 return NULL;
1309         }
1310
1311         talloc_free(mem_ctx);
1312
1313         talloc_free(frame);
1314         return py_group_map;
1315 }
1316
1317
1318 static PyTypeObject PyGroupmap = {
1319         .tp_name = "passdb.Groupmap",
1320         .tp_basicsize = sizeof(pytalloc_Object),
1321         .tp_getset = py_groupmap_getsetters,
1322         .tp_methods = NULL,
1323         .tp_new = py_groupmap_new,
1324         .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
1325         .tp_doc = "Groupmap() -> group map object\n",
1326 };
1327
1328
1329 static PyObject *py_pdb_domain_info(pytalloc_Object *self, PyObject *args)
1330 {
1331         TALLOC_CTX *frame = talloc_stackframe();
1332         struct pdb_methods *methods;
1333         struct pdb_domain_info *domain_info;
1334         PyObject *py_domain_info;
1335         struct dom_sid *sid;
1336         struct GUID *guid;
1337
1338         methods = pytalloc_get_ptr(self);
1339
1340         domain_info = methods->get_domain_info(methods, frame);
1341         if (! domain_info) {
1342                 Py_RETURN_NONE;
1343         }
1344
1345         sid = dom_sid_dup(frame, &domain_info->sid);
1346         if (sid == NULL) {
1347                 PyErr_NoMemory();
1348                 talloc_free(frame);
1349                 return NULL;
1350         }
1351
1352         guid = talloc(frame, struct GUID);
1353         if (guid == NULL) {
1354                 PyErr_NoMemory();
1355                 talloc_free(frame);
1356                 return NULL;
1357         }
1358         *guid = domain_info->guid;
1359
1360         if ((py_domain_info = PyDict_New()) == NULL) {
1361                 PyErr_NoMemory();
1362                 talloc_free(frame);
1363                 return NULL;
1364         }
1365
1366         PyDict_SetItemString(py_domain_info, "name", PyString_FromString(domain_info->name));
1367         PyDict_SetItemString(py_domain_info, "dns_domain", PyString_FromString(domain_info->dns_domain));
1368         PyDict_SetItemString(py_domain_info, "dns_forest", PyString_FromString(domain_info->dns_forest));
1369         PyDict_SetItemString(py_domain_info, "dom_sid", pytalloc_steal(dom_sid_Type, sid));
1370         PyDict_SetItemString(py_domain_info, "guid", pytalloc_steal(guid_Type, guid));
1371
1372         talloc_free(frame);
1373         return py_domain_info;
1374 }
1375
1376
1377 static PyObject *py_pdb_getsampwnam(pytalloc_Object *self, PyObject *args)
1378 {
1379         TALLOC_CTX *frame = talloc_stackframe();
1380         NTSTATUS status;
1381         const char *username;
1382         struct pdb_methods *methods;
1383         struct samu *sam_acct;
1384         PyObject *py_sam_acct;
1385
1386         if (!PyArg_ParseTuple(args, "s:getsampwnam", &username)) {
1387                 talloc_free(frame);
1388                 return NULL;
1389         }
1390
1391         methods = pytalloc_get_ptr(self);
1392
1393         py_sam_acct = py_samu_new(&PySamu, NULL, NULL);
1394         if (py_sam_acct == NULL) {
1395                 PyErr_NoMemory();
1396                 talloc_free(frame);
1397                 return NULL;
1398         }
1399         sam_acct = (struct samu *)pytalloc_get_ptr(py_sam_acct);
1400
1401         status = methods->getsampwnam(methods, sam_acct, username);
1402         if (!NT_STATUS_IS_OK(status)) {
1403                 PyErr_Format(py_pdb_error, "Unable to get user information for '%s', (%d,%s)",
1404                                 username,
1405                                 NT_STATUS_V(status),
1406                                 get_friendly_nt_error_msg(status));
1407                 Py_DECREF(py_sam_acct);
1408                 talloc_free(frame);
1409                 return NULL;
1410         }
1411
1412         talloc_free(frame);
1413         return py_sam_acct;
1414 }
1415
1416 static PyObject *py_pdb_getsampwsid(pytalloc_Object *self, PyObject *args)
1417 {
1418         TALLOC_CTX *frame = talloc_stackframe();
1419         NTSTATUS status;
1420         struct pdb_methods *methods;
1421         struct samu *sam_acct;
1422         PyObject *py_sam_acct;
1423         PyObject *py_user_sid;
1424
1425         if (!PyArg_ParseTuple(args, "O:getsampwsid", &py_user_sid)) {
1426                 talloc_free(frame);
1427                 return NULL;
1428         }
1429
1430         methods = pytalloc_get_ptr(self);
1431
1432         py_sam_acct = py_samu_new(&PySamu, NULL, NULL);
1433         if (py_sam_acct == NULL) {
1434                 PyErr_NoMemory();
1435                 talloc_free(frame);
1436                 return NULL;
1437         }
1438         sam_acct = (struct samu *)pytalloc_get_ptr(py_sam_acct);
1439
1440         status = methods->getsampwsid(methods, sam_acct, pytalloc_get_ptr(py_user_sid));
1441         if (!NT_STATUS_IS_OK(status)) {
1442                 PyErr_Format(py_pdb_error, "Unable to get user information from SID, (%d,%s)",
1443                                 NT_STATUS_V(status),
1444                                 get_friendly_nt_error_msg(status));
1445                 Py_DECREF(py_sam_acct);
1446                 talloc_free(frame);
1447                 return NULL;
1448         }
1449
1450         talloc_free(frame);
1451         return py_sam_acct;
1452 }
1453
1454 static PyObject *py_pdb_create_user(pytalloc_Object *self, PyObject *args)
1455 {
1456         TALLOC_CTX *frame = talloc_stackframe();
1457         NTSTATUS status;
1458         struct pdb_methods *methods;
1459         const char *username;
1460         unsigned int acct_flags;
1461         unsigned int rid;
1462
1463         if (!PyArg_ParseTuple(args, "sI:create_user", &username, &acct_flags)) {
1464                 talloc_free(frame);
1465                 return NULL;
1466         }
1467
1468         methods = pytalloc_get_ptr(self);
1469
1470         status = methods->create_user(methods, frame, username, acct_flags, &rid);
1471         if (!NT_STATUS_IS_OK(status)) {
1472                 PyErr_Format(py_pdb_error, "Unable to create user (%s), (%d,%s)",
1473                                 username,
1474                                 NT_STATUS_V(status),
1475                                 get_friendly_nt_error_msg(status));
1476                 talloc_free(frame);
1477                 return NULL;
1478         }
1479
1480         talloc_free(frame);
1481         return PyInt_FromLong(rid);
1482 }
1483
1484 static PyObject *py_pdb_delete_user(pytalloc_Object *self, PyObject *args)
1485 {
1486         TALLOC_CTX *frame = talloc_stackframe();
1487         NTSTATUS status;
1488         struct pdb_methods *methods;
1489         struct samu *sam_acct;
1490         PyObject *py_sam_acct;
1491
1492         if (!PyArg_ParseTuple(args, "O!:delete_user", &PySamu, &py_sam_acct)) {
1493                 talloc_free(frame);
1494                 return NULL;
1495         }
1496
1497         methods = pytalloc_get_ptr(self);
1498
1499         sam_acct = pytalloc_get_ptr(py_sam_acct);
1500
1501         status = methods->delete_user(methods, frame, sam_acct);
1502         if (!NT_STATUS_IS_OK(status)) {
1503                 PyErr_Format(py_pdb_error, "Unable to delete user, (%d,%s)",
1504                                 NT_STATUS_V(status),
1505                                 get_friendly_nt_error_msg(status));
1506                 talloc_free(frame);
1507                 return NULL;
1508         }
1509
1510         Py_RETURN_NONE;
1511         talloc_free(frame);
1512 }
1513
1514 static PyObject *py_pdb_add_sam_account(pytalloc_Object *self, PyObject *args)
1515 {
1516         TALLOC_CTX *frame = talloc_stackframe();
1517         NTSTATUS status;
1518         struct pdb_methods *methods;
1519         struct samu *sam_acct;
1520         PyObject *py_sam_acct;
1521
1522         if (!PyArg_ParseTuple(args, "O!:add_sam_account", &PySamu, &py_sam_acct)) {
1523                 talloc_free(frame);
1524                 return NULL;
1525         }
1526
1527         methods = pytalloc_get_ptr(self);
1528
1529         sam_acct = pytalloc_get_ptr(py_sam_acct);
1530
1531         status = methods->add_sam_account(methods, sam_acct);
1532         if (!NT_STATUS_IS_OK(status)) {
1533                 PyErr_Format(py_pdb_error, "Unable to add sam account '%s', (%d,%s)",
1534                                 sam_acct->username,
1535                                 NT_STATUS_V(status),
1536                                 get_friendly_nt_error_msg(status));
1537                 talloc_free(frame);
1538                 return NULL;
1539         }
1540
1541         Py_RETURN_NONE;
1542         talloc_free(frame);
1543 }
1544
1545 static PyObject *py_pdb_update_sam_account(pytalloc_Object *self, PyObject *args)
1546 {
1547         TALLOC_CTX *frame = talloc_stackframe();
1548         NTSTATUS status;
1549         struct pdb_methods *methods;
1550         struct samu *sam_acct;
1551         PyObject *py_sam_acct;
1552
1553         if (!PyArg_ParseTuple(args, "O!:update_sam_account", &PySamu, &py_sam_acct)) {
1554                 talloc_free(frame);
1555                 return NULL;
1556         }
1557
1558         methods = pytalloc_get_ptr(self);
1559
1560         sam_acct = pytalloc_get_ptr(py_sam_acct);
1561
1562         status = methods->update_sam_account(methods, sam_acct);
1563         if (!NT_STATUS_IS_OK(status)) {
1564                 PyErr_Format(py_pdb_error, "Unable to update sam account, (%d,%s)",
1565                                 NT_STATUS_V(status),
1566                                 get_friendly_nt_error_msg(status));
1567                 talloc_free(frame);
1568                 return NULL;
1569         }
1570
1571         Py_RETURN_NONE;
1572         talloc_free(frame);
1573 }
1574
1575 static PyObject *py_pdb_delete_sam_account(pytalloc_Object *self, PyObject *args)
1576 {
1577         TALLOC_CTX *frame = talloc_stackframe();
1578         NTSTATUS status;
1579         struct pdb_methods *methods;
1580         struct samu *sam_acct;
1581         PyObject *py_sam_acct;
1582
1583         if (!PyArg_ParseTuple(args, "O!:delete_sam_account", &PySamu, &py_sam_acct)) {
1584                 talloc_free(frame);
1585                 return NULL;
1586         }
1587
1588         methods = pytalloc_get_ptr(self);
1589
1590         sam_acct = pytalloc_get_ptr(py_sam_acct);
1591
1592         status = methods->delete_sam_account(methods, sam_acct);
1593         if (!NT_STATUS_IS_OK(status)) {
1594                 PyErr_Format(py_pdb_error, "Unable to delete sam account, (%d,%s)",
1595                                 NT_STATUS_V(status),
1596                                 get_friendly_nt_error_msg(status));
1597                 talloc_free(frame);
1598                 return NULL;
1599         }
1600
1601         Py_RETURN_NONE;
1602         talloc_free(frame);
1603 }
1604
1605 static PyObject *py_pdb_rename_sam_account(pytalloc_Object *self, PyObject *args)
1606 {
1607         TALLOC_CTX *frame = talloc_stackframe();
1608         NTSTATUS status;
1609         struct pdb_methods *methods;
1610         struct samu *sam_acct;
1611         const char *new_username;
1612         PyObject *py_sam_acct;
1613
1614         if (!PyArg_ParseTuple(args, "O!s:rename_sam_account", &PySamu, &py_sam_acct,
1615                                         &new_username)) {
1616                 talloc_free(frame);
1617                 return NULL;
1618         }
1619
1620         methods = pytalloc_get_ptr(self);
1621
1622         sam_acct = pytalloc_get_ptr(py_sam_acct);
1623
1624         status = methods->rename_sam_account(methods, sam_acct, new_username);
1625         if (!NT_STATUS_IS_OK(status)) {
1626                 PyErr_Format(py_pdb_error, "Unable to rename sam account, (%d,%s)",
1627                                 NT_STATUS_V(status),
1628                                 get_friendly_nt_error_msg(status));
1629                 talloc_free(frame);
1630                 return NULL;
1631         }
1632
1633         Py_RETURN_NONE;
1634         talloc_free(frame);
1635 }
1636
1637
1638 static PyObject *py_pdb_getgrsid(pytalloc_Object *self, PyObject *args)
1639 {
1640         TALLOC_CTX *frame = talloc_stackframe();
1641         NTSTATUS status;
1642         struct pdb_methods *methods;
1643         GROUP_MAP *group_map;
1644         struct dom_sid *domain_sid;
1645         PyObject *py_domain_sid, *py_group_map;
1646
1647         if (!PyArg_ParseTuple(args, "O!:getgrsid", dom_sid_Type, &py_domain_sid)) {
1648                 talloc_free(frame);
1649                 return NULL;
1650         }
1651
1652         methods = pytalloc_get_ptr(self);
1653
1654         domain_sid = pytalloc_get_ptr(py_domain_sid);
1655
1656         py_group_map = py_groupmap_new(&PyGroupmap, NULL, NULL);
1657         if (py_group_map == NULL) {
1658                 PyErr_NoMemory();
1659                 talloc_free(frame);
1660                 return NULL;
1661         }
1662
1663         group_map = pytalloc_get_ptr(py_group_map);
1664
1665         status = methods->getgrsid(methods, group_map, *domain_sid);
1666         if (!NT_STATUS_IS_OK(status)) {
1667                 PyErr_Format(py_pdb_error, "Unable to get group information by sid, (%d,%s)",
1668                                 NT_STATUS_V(status),
1669                                 get_friendly_nt_error_msg(status));
1670                 talloc_free(frame);
1671                 return NULL;
1672         }
1673
1674         talloc_free(frame);
1675         return py_group_map;
1676 }
1677
1678
1679 static PyObject *py_pdb_getgrgid(pytalloc_Object *self, PyObject *args)
1680 {
1681         TALLOC_CTX *frame = talloc_stackframe();
1682         NTSTATUS status;
1683         struct pdb_methods *methods;
1684         GROUP_MAP *group_map;
1685         PyObject *py_group_map;
1686         unsigned int gid_value;
1687
1688         if (!PyArg_ParseTuple(args, "I:getgrgid", &gid_value)) {
1689                 talloc_free(frame);
1690                 return NULL;
1691         }
1692
1693         methods = pytalloc_get_ptr(self);
1694
1695         py_group_map = py_groupmap_new(&PyGroupmap, NULL, NULL);
1696         if (py_group_map == NULL) {
1697                 PyErr_NoMemory();
1698                 talloc_free(frame);
1699                 return NULL;
1700         }
1701
1702         group_map = pytalloc_get_ptr(py_group_map);
1703
1704         status = methods->getgrgid(methods, group_map, gid_value);
1705         if (!NT_STATUS_IS_OK(status)) {
1706                 PyErr_Format(py_pdb_error, "Unable to get group information by gid, (%d,%s)",
1707                                 NT_STATUS_V(status),
1708                                 get_friendly_nt_error_msg(status));
1709                 talloc_free(frame);
1710                 return NULL;
1711         }
1712
1713         talloc_free(frame);
1714         return py_group_map;
1715 }
1716
1717
1718 static PyObject *py_pdb_getgrnam(pytalloc_Object *self, PyObject *args)
1719 {
1720         TALLOC_CTX *frame = talloc_stackframe();
1721         NTSTATUS status;
1722         struct pdb_methods *methods;
1723         GROUP_MAP *group_map;
1724         PyObject *py_group_map;
1725         const char *groupname;
1726
1727         if (!PyArg_ParseTuple(args, "s:getgrnam", &groupname)) {
1728                 talloc_free(frame);
1729                 return NULL;
1730         }
1731
1732         methods = pytalloc_get_ptr(self);
1733
1734         py_group_map = py_groupmap_new(&PyGroupmap, NULL, NULL);
1735         if (py_group_map == NULL) {
1736                 PyErr_NoMemory();
1737                 talloc_free(frame);
1738                 return NULL;
1739         }
1740
1741         group_map = pytalloc_get_ptr(py_group_map);
1742
1743         status = methods->getgrnam(methods, group_map, groupname);
1744         if (!NT_STATUS_IS_OK(status)) {
1745                 PyErr_Format(py_pdb_error, "Unable to get group information by name, (%d,%s)",
1746                                 NT_STATUS_V(status),
1747                                 get_friendly_nt_error_msg(status));
1748                 talloc_free(frame);
1749                 return NULL;
1750         }
1751
1752         talloc_free(frame);
1753         return py_group_map;
1754 }
1755
1756
1757 static PyObject *py_pdb_create_dom_group(pytalloc_Object *self, PyObject *args)
1758 {
1759         TALLOC_CTX *frame = talloc_stackframe();
1760         NTSTATUS status;
1761         struct pdb_methods *methods;
1762         const char *groupname;
1763         uint32_t group_rid;
1764
1765         if (!PyArg_ParseTuple(args, "s:create_dom_group", &groupname)) {
1766                 talloc_free(frame);
1767                 return NULL;
1768         }
1769
1770         methods = pytalloc_get_ptr(self);
1771
1772         status = methods->create_dom_group(methods, frame, groupname, &group_rid);
1773         if (!NT_STATUS_IS_OK(status)) {
1774                 PyErr_Format(py_pdb_error, "Unable to create domain group (%s), (%d,%s)",
1775                                 groupname,
1776                                 NT_STATUS_V(status),
1777                                 get_friendly_nt_error_msg(status));
1778                 talloc_free(frame);
1779                 return NULL;
1780         }
1781
1782         talloc_free(frame);
1783         return PyInt_FromLong(group_rid);
1784 }
1785
1786
1787 static PyObject *py_pdb_delete_dom_group(pytalloc_Object *self, PyObject *args)
1788 {
1789         TALLOC_CTX *frame = talloc_stackframe();
1790         NTSTATUS status;
1791         struct pdb_methods *methods;
1792         unsigned int group_rid;
1793
1794         if (!PyArg_ParseTuple(args, "I:delete_dom_group", &group_rid)) {
1795                 talloc_free(frame);
1796                 return NULL;
1797         }
1798
1799         methods = pytalloc_get_ptr(self);
1800
1801         status = methods->delete_dom_group(methods, frame, group_rid);
1802         if (!NT_STATUS_IS_OK(status)) {
1803                 PyErr_Format(py_pdb_error, "Unable to delete domain group (rid=%d), (%d,%s)",
1804                                 group_rid,
1805                                 NT_STATUS_V(status),
1806                                 get_friendly_nt_error_msg(status));
1807                 talloc_free(frame);
1808                 return NULL;
1809         }
1810
1811         Py_RETURN_NONE;
1812         talloc_free(frame);
1813 }
1814
1815
1816 static PyObject *py_pdb_add_group_mapping_entry(pytalloc_Object *self, PyObject *args)
1817 {
1818         TALLOC_CTX *frame = talloc_stackframe();
1819         NTSTATUS status;
1820         struct pdb_methods *methods;
1821         PyObject *py_group_map;
1822         GROUP_MAP *group_map;
1823
1824         if (!PyArg_ParseTuple(args, "O!:add_group_mapping_entry", &PyGroupmap, &py_group_map)) {
1825                 talloc_free(frame);
1826                 return NULL;
1827         }
1828
1829         methods = pytalloc_get_ptr(self);
1830
1831         group_map = pytalloc_get_ptr(py_group_map);
1832
1833         status = methods->add_group_mapping_entry(methods, group_map);
1834         if (!NT_STATUS_IS_OK(status)) {
1835                 PyErr_Format(py_pdb_error, "Unable to add group mapping entry, (%d,%s)",
1836                                 NT_STATUS_V(status),
1837                                 get_friendly_nt_error_msg(status));
1838                 talloc_free(frame);
1839                 return NULL;
1840         }
1841
1842         Py_RETURN_NONE;
1843         talloc_free(frame);
1844 }
1845
1846
1847 static PyObject *py_pdb_update_group_mapping_entry(pytalloc_Object *self, PyObject *args)
1848 {
1849         TALLOC_CTX *frame = talloc_stackframe();
1850         NTSTATUS status;
1851         struct pdb_methods *methods;
1852         PyObject *py_group_map;
1853         GROUP_MAP *group_map;
1854
1855         if (!PyArg_ParseTuple(args, "O!:update_group_mapping_entry", &PyGroupmap, &py_group_map)) {
1856                 talloc_free(frame);
1857                 return NULL;
1858         }
1859
1860         methods = pytalloc_get_ptr(self);
1861
1862         group_map = pytalloc_get_ptr(py_group_map);
1863
1864         status = methods->update_group_mapping_entry(methods, group_map);
1865         if (!NT_STATUS_IS_OK(status)) {
1866                 PyErr_Format(py_pdb_error, "Unable to update group mapping entry, (%d,%s)",
1867                                 NT_STATUS_V(status),
1868                                 get_friendly_nt_error_msg(status));
1869                 talloc_free(frame);
1870                 return NULL;
1871         }
1872
1873         Py_RETURN_NONE;
1874         talloc_free(frame);
1875 }
1876
1877
1878 static PyObject *py_pdb_delete_group_mapping_entry(pytalloc_Object *self, PyObject *args)
1879 {
1880         TALLOC_CTX *frame = talloc_stackframe();
1881         NTSTATUS status;
1882         struct pdb_methods *methods;
1883         PyObject *py_group_sid;
1884         struct dom_sid *group_sid;
1885
1886         if (!PyArg_ParseTuple(args, "O!:delete_group_mapping_entry", dom_sid_Type, &py_group_sid)) {
1887                 talloc_free(frame);
1888                 return NULL;
1889         }
1890
1891         methods = pytalloc_get_ptr(self);
1892
1893         group_sid = pytalloc_get_ptr(py_group_sid);
1894
1895         status = methods->delete_group_mapping_entry(methods, *group_sid);
1896         if (!NT_STATUS_IS_OK(status)) {
1897                 PyErr_Format(py_pdb_error, "Unable to delete group mapping entry, (%d,%s)",
1898                                 NT_STATUS_V(status),
1899                                 get_friendly_nt_error_msg(status));
1900                 talloc_free(frame);
1901                 return NULL;
1902         }
1903
1904         Py_RETURN_NONE;
1905         talloc_free(frame);
1906 }
1907
1908
1909 static PyObject *py_pdb_enum_group_mapping(pytalloc_Object *self, PyObject *args)
1910 {
1911         TALLOC_CTX *frame = talloc_stackframe();
1912         NTSTATUS status;
1913         struct pdb_methods *methods;
1914         enum lsa_SidType sid_name_use;
1915         int lsa_sidtype_value = SID_NAME_UNKNOWN;
1916         int unix_only = 0;
1917         PyObject *py_domain_sid;
1918         struct dom_sid *domain_sid = NULL;
1919         GROUP_MAP **gmap = NULL;
1920         GROUP_MAP *group_map;
1921         size_t num_entries;
1922         PyObject *py_gmap_list, *py_group_map;
1923         int i;
1924
1925         py_domain_sid = Py_None;
1926         Py_INCREF(Py_None);
1927
1928         if (!PyArg_ParseTuple(args, "|O!ii:enum_group_mapping", dom_sid_Type, &py_domain_sid,
1929                                         &lsa_sidtype_value, &unix_only)) {
1930                 talloc_free(frame);
1931                 return NULL;
1932         }
1933
1934         methods = pytalloc_get_ptr(self);
1935
1936         sid_name_use = lsa_sidtype_value;
1937
1938         if (py_domain_sid != Py_None) {
1939                 domain_sid = pytalloc_get_ptr(py_domain_sid);
1940         }
1941
1942         status = methods->enum_group_mapping(methods, domain_sid, sid_name_use,
1943                                                 &gmap, &num_entries, unix_only);
1944         if (!NT_STATUS_IS_OK(status)) {
1945                 PyErr_Format(py_pdb_error, "Unable to enumerate group mappings, (%d,%s)",
1946                                 NT_STATUS_V(status),
1947                                 get_friendly_nt_error_msg(status));
1948                 talloc_free(frame);
1949                 return NULL;
1950         }
1951
1952         py_gmap_list = PyList_New(0);
1953         if (py_gmap_list == NULL) {
1954                 PyErr_NoMemory();
1955                 talloc_free(frame);
1956                 return NULL;
1957         }
1958
1959         for(i=0; i<num_entries; i++) {
1960                 py_group_map = py_groupmap_new(&PyGroupmap, NULL, NULL);
1961                 if (py_group_map) {
1962                         group_map = pytalloc_get_ptr(py_group_map);
1963                         *group_map = *gmap[i];
1964                         talloc_steal(group_map, gmap[i]->nt_name);
1965                         talloc_steal(group_map, gmap[i]->comment);
1966
1967                         PyList_Append(py_gmap_list, py_group_map);
1968                 }
1969         }
1970
1971         talloc_free(gmap);
1972
1973         talloc_free(frame);
1974         return py_gmap_list;
1975 }
1976
1977
1978 static PyObject *py_pdb_enum_group_members(pytalloc_Object *self, PyObject *args)
1979 {
1980         TALLOC_CTX *frame = talloc_stackframe();
1981         NTSTATUS status;
1982         struct pdb_methods *methods;
1983         PyObject *py_group_sid;
1984         struct dom_sid *group_sid;
1985         uint32_t *member_rids;
1986         size_t num_members;
1987         PyObject *py_sid_list;
1988         struct dom_sid *domain_sid, *member_sid;
1989         int i;
1990
1991         if (!PyArg_ParseTuple(args, "O!:enum_group_members", dom_sid_Type, &py_group_sid)) {
1992                 talloc_free(frame);
1993                 return NULL;
1994         }
1995
1996         methods = pytalloc_get_ptr(self);
1997
1998         group_sid = pytalloc_get_ptr(py_group_sid);
1999
2000         status = methods->enum_group_members(methods, frame, group_sid,
2001                                                 &member_rids, &num_members);
2002         if (!NT_STATUS_IS_OK(status)) {
2003                 PyErr_Format(py_pdb_error, "Unable to enumerate group members, (%d,%s)",
2004                                 NT_STATUS_V(status),
2005                                 get_friendly_nt_error_msg(status));
2006                 talloc_free(frame);
2007                 return NULL;
2008         }
2009
2010         py_sid_list = PyList_New(0);
2011         if (py_sid_list == NULL) {
2012                 PyErr_NoMemory();
2013                 talloc_free(frame);
2014                 return NULL;
2015         }
2016
2017         domain_sid = get_global_sam_sid();
2018
2019         for(i=0; i<num_members; i++) {
2020                 member_sid = dom_sid_add_rid(frame, domain_sid, member_rids[i]);
2021                 PyList_Append(py_sid_list, pytalloc_steal(dom_sid_Type, member_sid));
2022         }
2023
2024         talloc_free(frame);
2025         return py_sid_list;
2026 }
2027
2028
2029 static PyObject *py_pdb_enum_group_memberships(pytalloc_Object *self, PyObject *args)
2030 {
2031         TALLOC_CTX *frame = talloc_stackframe();
2032         NTSTATUS status;
2033         struct pdb_methods *methods;
2034         int i;
2035
2036         struct samu *sam_acct;
2037         PyObject *py_sam_acct;
2038         PyObject *py_sid_list;
2039         struct dom_sid *user_group_sids = NULL;
2040         gid_t *user_group_ids = NULL;
2041         uint32_t num_groups = 0;
2042
2043         if (!PyArg_ParseTuple(args, "O!:enum_group_memberships", &PySamu, &py_sam_acct)) {
2044                 talloc_free(frame);
2045                 return NULL;
2046         }
2047
2048         methods = pytalloc_get_ptr(self);
2049
2050         sam_acct = pytalloc_get_ptr(py_sam_acct);
2051
2052         status = methods->enum_group_memberships(methods, frame, sam_acct,
2053                                                  &user_group_sids, &user_group_ids, &num_groups);
2054         if (!NT_STATUS_IS_OK(status)) {
2055                 PyErr_Format(py_pdb_error, "Unable to enumerate group memberships, (%d,%s)",
2056                                 NT_STATUS_V(status),
2057                                 get_friendly_nt_error_msg(status));
2058                 talloc_free(frame);
2059                 return NULL;
2060         }
2061
2062         py_sid_list = PyList_New(0);
2063         if (py_sid_list == NULL) {
2064                 PyErr_NoMemory();
2065                 talloc_free(frame);
2066                 return NULL;
2067         }
2068
2069         for(i=0; i<num_groups; i++) {
2070                 PyList_Append(py_sid_list, pytalloc_steal(dom_sid_Type, dom_sid_dup(NULL, &user_group_sids[i])));
2071         }
2072
2073         talloc_free(frame);
2074         return py_sid_list;
2075 }
2076
2077
2078 static PyObject *py_pdb_add_groupmem(pytalloc_Object *self, PyObject *args)
2079 {
2080         TALLOC_CTX *frame = talloc_stackframe();
2081         NTSTATUS status;
2082         struct pdb_methods *methods;
2083         uint32_t group_rid, member_rid;
2084
2085         if (!PyArg_ParseTuple(args, "II:add_groupmem", &group_rid, &member_rid)) {
2086                 talloc_free(frame);
2087                 return NULL;
2088         }
2089
2090         methods = pytalloc_get_ptr(self);
2091
2092         status = methods->add_groupmem(methods, frame, group_rid, member_rid);
2093         if (!NT_STATUS_IS_OK(status)) {
2094                 PyErr_Format(py_pdb_error, "Unable to add group member, (%d,%s)",
2095                                 NT_STATUS_V(status),
2096                                 get_friendly_nt_error_msg(status));
2097                 talloc_free(frame);
2098                 return NULL;
2099         }
2100
2101         Py_RETURN_NONE;
2102         talloc_free(frame);
2103 }
2104
2105
2106 static PyObject *py_pdb_del_groupmem(pytalloc_Object *self, PyObject *args)
2107 {
2108         TALLOC_CTX *frame = talloc_stackframe();
2109         NTSTATUS status;
2110         struct pdb_methods *methods;
2111         uint32_t group_rid, member_rid;
2112
2113         if (!PyArg_ParseTuple(args, "II:del_groupmem", &group_rid, &member_rid)) {
2114                 talloc_free(frame);
2115                 return NULL;
2116         }
2117
2118         methods = pytalloc_get_ptr(self);
2119
2120         status = methods->del_groupmem(methods, frame, group_rid, member_rid);
2121         if (!NT_STATUS_IS_OK(status)) {
2122                 PyErr_Format(py_pdb_error, "Unable to rename sam account, (%d,%s)",
2123                                 NT_STATUS_V(status),
2124                                 get_friendly_nt_error_msg(status));
2125                 talloc_free(frame);
2126                 return NULL;
2127         }
2128
2129         Py_RETURN_NONE;
2130         talloc_free(frame);
2131 }
2132
2133
2134 static PyObject *py_pdb_create_alias(pytalloc_Object *self, PyObject *args)
2135 {
2136         TALLOC_CTX *frame = talloc_stackframe();
2137         NTSTATUS status;
2138         struct pdb_methods *methods;
2139         const char *alias_name;
2140         uint32_t rid;
2141
2142         if (!PyArg_ParseTuple(args, "s:create_alias", &alias_name)) {
2143                 talloc_free(frame);
2144                 return NULL;
2145         }
2146
2147         methods = pytalloc_get_ptr(self);
2148
2149         status = methods->create_alias(methods, alias_name, &rid);
2150         if (!NT_STATUS_IS_OK(status)) {
2151                 PyErr_Format(py_pdb_error, "Unable to create alias (%s), (%d,%s)",
2152                                 alias_name,
2153                                 NT_STATUS_V(status),
2154                                 get_friendly_nt_error_msg(status));
2155                 talloc_free(frame);
2156                 return NULL;
2157         }
2158
2159         talloc_free(frame);
2160         return PyInt_FromLong(rid);
2161 }
2162
2163
2164 static PyObject *py_pdb_delete_alias(pytalloc_Object *self, PyObject *args)
2165 {
2166         TALLOC_CTX *frame = talloc_stackframe();
2167         NTSTATUS status;
2168         struct pdb_methods *methods;
2169         PyObject *py_alias_sid;
2170         struct dom_sid *alias_sid;
2171
2172         if (!PyArg_ParseTuple(args, "O!:delete_alias", dom_sid_Type, &py_alias_sid)) {
2173                 talloc_free(frame);
2174                 return NULL;
2175         }
2176
2177         methods = pytalloc_get_ptr(self);
2178
2179         alias_sid = pytalloc_get_ptr(py_alias_sid);
2180
2181         status = methods->delete_alias(methods, alias_sid);
2182         if (!NT_STATUS_IS_OK(status)) {
2183                 PyErr_Format(py_pdb_error, "Unable to delete alias, (%d,%s)",
2184                                 NT_STATUS_V(status),
2185                                 get_friendly_nt_error_msg(status));
2186                 talloc_free(frame);
2187                 return NULL;
2188         }
2189
2190         Py_RETURN_NONE;
2191         talloc_free(frame);
2192 }
2193
2194
2195 static PyObject *py_pdb_get_aliasinfo(pytalloc_Object *self, PyObject *args)
2196 {
2197         TALLOC_CTX *frame = talloc_stackframe();
2198         NTSTATUS status;
2199         struct pdb_methods *methods;
2200         PyObject *py_alias_sid;
2201         struct dom_sid *alias_sid;
2202         struct acct_info *alias_info;
2203         PyObject *py_alias_info;
2204
2205         if (!PyArg_ParseTuple(args, "O!:get_aliasinfo", dom_sid_Type, &py_alias_sid)) {
2206                 talloc_free(frame);
2207                 return NULL;
2208         }
2209
2210         methods = pytalloc_get_ptr(self);
2211
2212         alias_sid = pytalloc_get_ptr(py_alias_sid);
2213
2214         alias_info = talloc_zero(frame, struct acct_info);
2215         if (!alias_info) {
2216                 PyErr_NoMemory();
2217                 talloc_free(frame);
2218                 return NULL;
2219         }
2220
2221         status = methods->get_aliasinfo(methods, alias_sid, alias_info);
2222         if (!NT_STATUS_IS_OK(status)) {
2223                 PyErr_Format(py_pdb_error, "Unable to get alias information, (%d,%s)",
2224                                 NT_STATUS_V(status),
2225                                 get_friendly_nt_error_msg(status));
2226                 talloc_free(frame);
2227                 return NULL;
2228         }
2229
2230         py_alias_info = PyDict_New();
2231         if (py_alias_info == NULL) {
2232                 PyErr_NoMemory();
2233                 talloc_free(frame);
2234                 return NULL;
2235         }
2236
2237         PyDict_SetItemString(py_alias_info, "acct_name",
2238                              PyString_FromString(alias_info->acct_name));
2239         PyDict_SetItemString(py_alias_info, "acct_desc",
2240                              PyString_FromString(alias_info->acct_desc));
2241         PyDict_SetItemString(py_alias_info, "rid",
2242                              PyInt_FromLong(alias_info->rid));
2243
2244         talloc_free(frame);
2245         return py_alias_info;
2246 }
2247
2248
2249 static PyObject *py_pdb_set_aliasinfo(pytalloc_Object *self, PyObject *args)
2250 {
2251         TALLOC_CTX *frame = talloc_stackframe();
2252         NTSTATUS status;
2253         struct pdb_methods *methods;
2254         PyObject *py_alias_sid, *py_alias_info;
2255         struct dom_sid *alias_sid;
2256         struct acct_info alias_info;
2257
2258         if (!PyArg_ParseTuple(args, "O!O:set_alias_info", dom_sid_Type, &py_alias_sid,
2259                                 &py_alias_info)) {
2260                 talloc_free(frame);
2261                 return NULL;
2262         }
2263
2264         methods = pytalloc_get_ptr(self);
2265
2266         alias_sid = pytalloc_get_ptr(py_alias_sid);
2267
2268         alias_info.acct_name = talloc_strdup(frame, PyString_AsString(PyDict_GetItemString(py_alias_info, "acct_name")));
2269         if (alias_info.acct_name == NULL) {
2270                 PyErr_Format(py_pdb_error, "Unable to allocate memory");
2271                 talloc_free(frame);
2272                 return NULL;
2273         }
2274         alias_info.acct_desc = talloc_strdup(frame, PyString_AsString(PyDict_GetItemString(py_alias_info, "acct_desc")));
2275         if (alias_info.acct_desc == NULL) {
2276                 PyErr_Format(py_pdb_error, "Unable to allocate memory");
2277                 talloc_free(frame);
2278                 return NULL;
2279         }
2280
2281         status = methods->set_aliasinfo(methods, alias_sid, &alias_info);
2282         if (!NT_STATUS_IS_OK(status)) {
2283                 PyErr_Format(py_pdb_error, "Unable to set alias information, (%d,%s)",
2284                                 NT_STATUS_V(status),
2285                                 get_friendly_nt_error_msg(status));
2286                 talloc_free(frame);
2287                 return NULL;
2288         }
2289
2290         Py_RETURN_NONE;
2291         talloc_free(frame);
2292 }
2293
2294
2295 static PyObject *py_pdb_add_aliasmem(pytalloc_Object *self, PyObject *args)
2296 {
2297         TALLOC_CTX *frame = talloc_stackframe();
2298         NTSTATUS status;
2299         struct pdb_methods *methods;
2300         PyObject *py_alias_sid, *py_member_sid;
2301         struct dom_sid *alias_sid, *member_sid;
2302
2303         if (!PyArg_ParseTuple(args, "O!O!:add_aliasmem", dom_sid_Type, &py_alias_sid,
2304                                         dom_sid_Type, &py_member_sid)) {
2305                 talloc_free(frame);
2306                 return NULL;
2307         }
2308
2309         methods = pytalloc_get_ptr(self);
2310
2311         alias_sid = pytalloc_get_ptr(py_alias_sid);
2312         member_sid = pytalloc_get_ptr(py_member_sid);
2313
2314         status = methods->add_aliasmem(methods, alias_sid, member_sid);
2315         if (!NT_STATUS_IS_OK(status)) {
2316                 PyErr_Format(py_pdb_error, "Unable to add member to alias, (%d,%s)",
2317                                 NT_STATUS_V(status),
2318                                 get_friendly_nt_error_msg(status));
2319                 talloc_free(frame);
2320                 return NULL;
2321         }
2322
2323         Py_RETURN_NONE;
2324         talloc_free(frame);
2325 }
2326
2327
2328 static PyObject *py_pdb_del_aliasmem(pytalloc_Object *self, PyObject *args)
2329 {
2330         TALLOC_CTX *frame = talloc_stackframe();
2331         NTSTATUS status;
2332         struct pdb_methods *methods;
2333         PyObject *py_alias_sid, *py_member_sid;
2334         const struct dom_sid *alias_sid, *member_sid;
2335
2336         if (!PyArg_ParseTuple(args, "O!O!:del_aliasmem", dom_sid_Type, &py_alias_sid,
2337                                         dom_sid_Type, &py_member_sid)) {
2338                 talloc_free(frame);
2339                 return NULL;
2340         }
2341
2342         methods = pytalloc_get_ptr(self);
2343
2344         alias_sid = pytalloc_get_ptr(py_alias_sid);
2345         member_sid = pytalloc_get_ptr(py_member_sid);
2346
2347         status = methods->del_aliasmem(methods, alias_sid, member_sid);
2348         if (!NT_STATUS_IS_OK(status)) {
2349                 PyErr_Format(py_pdb_error, "Unable to delete member from alias, (%d,%s)",
2350                                 NT_STATUS_V(status),
2351                                 get_friendly_nt_error_msg(status));
2352                 talloc_free(frame);
2353                 return NULL;
2354         }
2355
2356         Py_RETURN_NONE;
2357         talloc_free(frame);
2358 }
2359
2360
2361 static PyObject *py_pdb_enum_aliasmem(pytalloc_Object *self, PyObject *args)
2362 {
2363         TALLOC_CTX *frame = talloc_stackframe();
2364         NTSTATUS status;
2365         struct pdb_methods *methods;
2366         PyObject *py_alias_sid;
2367         struct dom_sid *alias_sid, *member_sid, *tmp_sid;
2368         PyObject *py_member_list, *py_member_sid;
2369         size_t num_members;
2370         int i;
2371
2372         if (!PyArg_ParseTuple(args, "O!:enum_aliasmem", dom_sid_Type, &py_alias_sid)) {
2373                 talloc_free(frame);
2374                 return NULL;
2375         }
2376
2377         methods = pytalloc_get_ptr(self);
2378
2379         alias_sid = pytalloc_get_ptr(py_alias_sid);
2380
2381         status = methods->enum_aliasmem(methods, alias_sid, frame, &member_sid, &num_members);
2382         if (!NT_STATUS_IS_OK(status)) {
2383                 PyErr_Format(py_pdb_error, "Unable to enumerate members for alias, (%d,%s)",
2384                                 NT_STATUS_V(status),
2385                                 get_friendly_nt_error_msg(status));
2386                 talloc_free(frame);
2387                 return NULL;
2388         }
2389
2390         py_member_list = PyList_New(0);
2391         if (py_member_list == NULL) {
2392                 PyErr_NoMemory();
2393                 talloc_free(frame);
2394                 return NULL;
2395         }
2396
2397         for(i=0; i<num_members; i++) {
2398                 py_member_sid = pytalloc_new(struct dom_sid, dom_sid_Type);
2399                 if (py_member_sid == NULL) {
2400                         PyErr_NoMemory();
2401                         talloc_free(frame);
2402                         return NULL;
2403                 }
2404                 tmp_sid = pytalloc_get_ptr(py_member_sid);
2405                 *tmp_sid = member_sid[i];
2406                 PyList_Append(py_member_list, py_member_sid);
2407         }
2408
2409         talloc_free(frame);
2410         return py_member_list;
2411 }
2412
2413
2414 static PyObject *py_pdb_get_account_policy(pytalloc_Object *self)
2415 {
2416         TALLOC_CTX *frame = talloc_stackframe();
2417         NTSTATUS status;
2418         struct pdb_methods *methods;
2419         PyObject *py_acct_policy;
2420         uint32_t value;
2421         const char **names;
2422         int count, i;
2423         enum pdb_policy_type type;
2424
2425         methods = pytalloc_get_ptr(self);
2426
2427         py_acct_policy = PyDict_New();
2428         if (py_acct_policy == NULL) {
2429                 PyErr_NoMemory();
2430                 talloc_free(frame);
2431                 return NULL;
2432         }
2433
2434         account_policy_names_list(frame, &names, &count);
2435         for (i=0; i<count; i++) {
2436                 type = account_policy_name_to_typenum(names[i]);
2437                 status = methods->get_account_policy(methods, type, &value);
2438                 if (NT_STATUS_IS_OK(status)) {
2439                         PyDict_SetItemString(py_acct_policy, names[i], Py_BuildValue("i", value));
2440                 }
2441         }
2442
2443         talloc_free(frame);
2444         return py_acct_policy;
2445 }
2446
2447
2448 static PyObject *py_pdb_set_account_policy(pytalloc_Object *self, PyObject *args)
2449 {
2450         TALLOC_CTX *frame = talloc_stackframe();
2451         NTSTATUS status;
2452         struct pdb_methods *methods;
2453         PyObject *py_acct_policy, *py_value;
2454         const char **names;
2455         int count, i;
2456         enum pdb_policy_type type;
2457
2458         if (!PyArg_ParseTuple(args, "O!:set_account_policy", PyDict_Type, &py_acct_policy)) {
2459                 talloc_free(frame);
2460                 return NULL;
2461         }
2462
2463         methods = pytalloc_get_ptr(self);
2464
2465         account_policy_names_list(frame, &names, &count);
2466         for (i=0; i<count; i++) {
2467                 if ((py_value = PyDict_GetItemString(py_acct_policy, names[i])) != NULL) {
2468                         type = account_policy_name_to_typenum(names[i]);
2469                         status = methods->set_account_policy(methods, type, PyInt_AsLong(py_value));
2470                         if (!NT_STATUS_IS_OK(status)) {
2471                                 PyErr_Format(py_pdb_error, "Error setting account policy (%s), (%d,%s)",
2472                                                 names[i],
2473                                                 NT_STATUS_V(status),
2474                                                 get_friendly_nt_error_msg(status));
2475                         }
2476                 }
2477         }
2478
2479         Py_RETURN_NONE;
2480         talloc_free(frame);
2481 }
2482
2483 static PyObject *py_pdb_search_users(pytalloc_Object *self, PyObject *args)
2484 {
2485         TALLOC_CTX *frame = talloc_stackframe();
2486         NTSTATUS status;
2487         struct pdb_methods *methods;
2488         unsigned int acct_flags;
2489         struct pdb_search *search;
2490         struct samr_displayentry *entry;
2491         PyObject *py_userlist, *py_dict;
2492
2493         if (!PyArg_ParseTuple(args, "I:search_users", &acct_flags)) {
2494                 talloc_free(frame);
2495                 return NULL;
2496         }
2497
2498         methods = pytalloc_get_ptr(self);
2499
2500         search = talloc_zero(frame, struct pdb_search);
2501         if (search == NULL) {
2502                 PyErr_NoMemory();
2503                 talloc_free(frame);
2504                 return NULL;
2505         }
2506
2507         if (!methods->search_users(methods, search, acct_flags)) {
2508                 PyErr_Format(py_pdb_error, "Unable to search users, (%d,%s)",
2509                                 NT_STATUS_V(status),
2510                                 get_friendly_nt_error_msg(status));
2511                 talloc_free(frame);
2512                 return NULL;
2513         }
2514
2515         entry = talloc_zero(frame, struct samr_displayentry);
2516         if (entry == NULL) {
2517                 PyErr_NoMemory();
2518                 talloc_free(frame);
2519                 return NULL;
2520         }
2521
2522         py_userlist = PyList_New(0);
2523         if (py_userlist == NULL) {
2524                 PyErr_NoMemory();
2525                 talloc_free(frame);
2526                 return NULL;
2527         }
2528
2529         while (search->next_entry(search, entry)) {
2530                 py_dict = PyDict_New();
2531                 if (py_dict == NULL) {
2532                         PyErr_NoMemory();
2533                 } else {
2534                         PyDict_SetItemString(py_dict, "idx", PyInt_FromLong(entry->idx));
2535                         PyDict_SetItemString(py_dict, "rid", PyInt_FromLong(entry->rid));
2536                         PyDict_SetItemString(py_dict, "acct_flags", PyInt_FromLong(entry->acct_flags));
2537                         PyDict_SetItemString(py_dict, "account_name", PyString_FromString(entry->account_name));
2538                         PyDict_SetItemString(py_dict, "fullname", PyString_FromString(entry->fullname));
2539                         PyDict_SetItemString(py_dict, "description", PyString_FromString(entry->description));
2540                         PyList_Append(py_userlist, py_dict);
2541                 }
2542         }
2543         search->search_end(search);
2544
2545         talloc_free(frame);
2546         return py_userlist;
2547 }
2548
2549
2550 static PyObject *py_pdb_search_groups(pytalloc_Object *self)
2551 {
2552         TALLOC_CTX *frame = talloc_stackframe();
2553         NTSTATUS status;
2554         struct pdb_methods *methods;
2555         struct pdb_search *search;
2556         struct samr_displayentry *entry;
2557         PyObject *py_grouplist, *py_dict;
2558
2559         methods = pytalloc_get_ptr(self);
2560
2561         search = talloc_zero(frame, struct pdb_search);
2562         if (search == NULL) {
2563                 PyErr_NoMemory();
2564                 talloc_free(frame);
2565                 return NULL;
2566         }
2567
2568         if (!methods->search_groups(methods, search)) {
2569                 PyErr_Format(py_pdb_error, "Unable to search groups, (%d,%s)",
2570                                 NT_STATUS_V(status),
2571                                 get_friendly_nt_error_msg(status));
2572                 talloc_free(frame);
2573                 return NULL;
2574         }
2575
2576         entry = talloc_zero(frame, struct samr_displayentry);
2577         if (entry == NULL) {
2578                 PyErr_NoMemory();
2579                 talloc_free(frame);
2580                 return NULL;
2581         }
2582
2583         py_grouplist = PyList_New(0);
2584         if (py_grouplist == NULL) {
2585                 PyErr_NoMemory();
2586                 talloc_free(frame);
2587                 return NULL;
2588         }
2589
2590         while (search->next_entry(search, entry)) {
2591                 py_dict = PyDict_New();
2592                 if (py_dict == NULL) {
2593                         PyErr_NoMemory();
2594                 } else {
2595                         PyDict_SetItemString(py_dict, "idx", PyInt_FromLong(entry->idx));
2596                         PyDict_SetItemString(py_dict, "rid", PyInt_FromLong(entry->rid));
2597                         PyDict_SetItemString(py_dict, "acct_flags", PyInt_FromLong(entry->acct_flags));
2598                         PyDict_SetItemString(py_dict, "account_name", PyString_FromString(entry->account_name));
2599                         PyDict_SetItemString(py_dict, "fullname", PyString_FromString(entry->fullname));
2600                         PyDict_SetItemString(py_dict, "description", PyString_FromString(entry->description));
2601                         PyList_Append(py_grouplist, py_dict);
2602                 }
2603         }
2604         search->search_end(search);
2605
2606         talloc_free(frame);
2607         return py_grouplist;
2608 }
2609
2610
2611 static PyObject *py_pdb_search_aliases(pytalloc_Object *self, PyObject *args)
2612 {
2613         TALLOC_CTX *frame = talloc_stackframe();
2614         struct pdb_methods *methods;
2615         struct pdb_search *search;
2616         struct samr_displayentry *entry;
2617         PyObject *py_aliaslist, *py_dict;
2618         PyObject *py_domain_sid;
2619         struct dom_sid *domain_sid = NULL;
2620
2621         py_domain_sid = Py_None;
2622         Py_INCREF(Py_None);
2623
2624         if (!PyArg_ParseTuple(args, "|O!:search_aliases", dom_sid_Type, &py_domain_sid)) {
2625                 talloc_free(frame);
2626                 return NULL;
2627         }
2628
2629         methods = pytalloc_get_ptr(self);
2630
2631         if (py_domain_sid != Py_None) {
2632                 domain_sid = pytalloc_get_ptr(py_domain_sid);
2633         }
2634
2635         search = talloc_zero(frame, struct pdb_search);
2636         if (search == NULL) {
2637                 PyErr_NoMemory();
2638                 talloc_free(frame);
2639                 return NULL;
2640         }
2641
2642         if (!methods->search_aliases(methods, search, domain_sid)) {
2643                 PyErr_Format(py_pdb_error, "Unable to search aliases");
2644                 talloc_free(frame);
2645                 return NULL;
2646         }
2647
2648         entry = talloc_zero(frame, struct samr_displayentry);
2649         if (entry == NULL) {
2650                 PyErr_NoMemory();
2651                 talloc_free(frame);
2652                 return NULL;
2653         }
2654
2655         py_aliaslist = PyList_New(0);
2656         if (py_aliaslist == NULL) {
2657                 PyErr_NoMemory();
2658                 talloc_free(frame);
2659                 return NULL;
2660         }
2661
2662         while (search->next_entry(search, entry)) {
2663                 py_dict = PyDict_New();
2664                 if (py_dict == NULL) {
2665                         PyErr_NoMemory();
2666                 } else {
2667                         PyDict_SetItemString(py_dict, "idx", PyInt_FromLong(entry->idx));
2668                         PyDict_SetItemString(py_dict, "rid", PyInt_FromLong(entry->rid));
2669                         PyDict_SetItemString(py_dict, "acct_flags", PyInt_FromLong(entry->acct_flags));
2670                         PyDict_SetItemString(py_dict, "account_name", PyString_FromString(entry->account_name));
2671                         PyDict_SetItemString(py_dict, "fullname", PyString_FromString(entry->fullname));
2672                         PyDict_SetItemString(py_dict, "description", PyString_FromString(entry->description));
2673                         PyList_Append(py_aliaslist, py_dict);
2674                 }
2675         }
2676         search->search_end(search);
2677
2678         talloc_free(frame);
2679         return py_aliaslist;
2680 }
2681
2682
2683 static PyObject *py_pdb_uid_to_sid(pytalloc_Object *self, PyObject *args)
2684 {
2685         TALLOC_CTX *frame = talloc_stackframe();
2686         struct pdb_methods *methods;
2687         unsigned int uid;
2688         struct dom_sid user_sid, *copy_user_sid;
2689         PyObject *py_user_sid;
2690
2691         if (!PyArg_ParseTuple(args, "I:uid_to_sid", &uid)) {
2692                 talloc_free(frame);
2693                 return NULL;
2694         }
2695
2696         methods = pytalloc_get_ptr(self);
2697
2698         if (!methods->uid_to_sid(methods, uid, &user_sid)) {
2699                 PyErr_Format(py_pdb_error, "Unable to get sid for uid=%d", uid);
2700                 talloc_free(frame);
2701                 return NULL;
2702         }
2703
2704         copy_user_sid = dom_sid_dup(frame, &user_sid);
2705         if (copy_user_sid == NULL) {
2706                 PyErr_NoMemory();
2707                 talloc_free(frame);
2708                 return NULL;
2709         }
2710
2711         py_user_sid = pytalloc_steal(dom_sid_Type, copy_user_sid);
2712
2713         talloc_free(frame);
2714         return py_user_sid;
2715 }
2716
2717
2718 static PyObject *py_pdb_gid_to_sid(pytalloc_Object *self, PyObject *args)
2719 {
2720         TALLOC_CTX *frame = talloc_stackframe();
2721         struct pdb_methods *methods;
2722         unsigned int gid;
2723         struct dom_sid group_sid, *copy_group_sid;
2724         PyObject *py_group_sid;
2725
2726         if (!PyArg_ParseTuple(args, "I:gid_to_sid", &gid)) {
2727                 talloc_free(frame);
2728                 return NULL;
2729         }
2730
2731         methods = pytalloc_get_ptr(self);
2732
2733         if (!methods->gid_to_sid(methods, gid, &group_sid)) {
2734                 PyErr_Format(py_pdb_error, "Unable to get sid for gid=%d", gid);
2735                 talloc_free(frame);
2736                 return NULL;
2737         }
2738
2739         copy_group_sid = dom_sid_dup(frame, &group_sid);
2740         if (copy_group_sid == NULL) {
2741                 PyErr_NoMemory();
2742                 talloc_free(frame);
2743                 return NULL;
2744         }
2745
2746         py_group_sid = pytalloc_steal(dom_sid_Type, copy_group_sid);
2747
2748         talloc_free(frame);
2749         return py_group_sid;
2750 }
2751
2752
2753 static PyObject *py_pdb_sid_to_id(pytalloc_Object *self, PyObject *args)
2754 {
2755         TALLOC_CTX *frame = talloc_stackframe();
2756         struct pdb_methods *methods;
2757         PyObject *py_sid;
2758         struct dom_sid *sid;
2759         struct unixid id;
2760
2761         if (!PyArg_ParseTuple(args, "O!:sid_to_id", dom_sid_Type, &py_sid)) {
2762                 talloc_free(frame);
2763                 return NULL;
2764         }
2765
2766         methods = pytalloc_get_ptr(self);
2767
2768         sid = pytalloc_get_ptr(py_sid);
2769
2770         if (!methods->sid_to_id(methods, sid, &id)) {
2771                 PyErr_Format(py_pdb_error, "Unable to get id for sid");
2772                 talloc_free(frame);
2773                 return NULL;
2774         }
2775
2776         talloc_free(frame);
2777         return Py_BuildValue("(II)", id.id, id.type);
2778 }
2779
2780
2781 static PyObject *py_pdb_new_rid(pytalloc_Object *self)
2782 {
2783         TALLOC_CTX *frame = talloc_stackframe();
2784         struct pdb_methods *methods;
2785         uint32_t rid;
2786
2787         methods = pytalloc_get_ptr(self);
2788
2789         if (!methods->new_rid(methods, &rid)) {
2790                 PyErr_Format(py_pdb_error, "Unable to get new rid");
2791                 talloc_free(frame);
2792                 return NULL;
2793         }
2794
2795         talloc_free(frame);
2796         return PyInt_FromLong(rid);
2797 }
2798
2799
2800 static PyObject *py_pdb_get_trusteddom_pw(pytalloc_Object *self, PyObject *args)
2801 {
2802         TALLOC_CTX *frame = talloc_stackframe();
2803         struct pdb_methods *methods;
2804         const char *domain;
2805         char *pwd;
2806         struct dom_sid sid, *copy_sid;
2807         PyObject *py_sid;
2808         time_t last_set_time;
2809         PyObject *py_value;
2810
2811         if (!PyArg_ParseTuple(args, "s:get_trusteddom_pw", &domain)) {
2812                 talloc_free(frame);
2813                 return NULL;
2814         }
2815
2816         methods = pytalloc_get_ptr(self);
2817
2818         if (!methods->get_trusteddom_pw(methods, domain, &pwd, &sid, &last_set_time)) {
2819                 PyErr_Format(py_pdb_error, "Unable to get trusted domain password");
2820                 talloc_free(frame);
2821                 return NULL;
2822         }
2823
2824         copy_sid = dom_sid_dup(frame, &sid);
2825         if (copy_sid == NULL) {
2826                 PyErr_NoMemory();
2827                 talloc_free(frame);
2828                 return NULL;
2829         }
2830
2831         py_sid = pytalloc_steal(dom_sid_Type, copy_sid);
2832         if (py_sid == NULL) {
2833                 PyErr_NoMemory();
2834                 talloc_free(frame);
2835                 return NULL;
2836         }
2837
2838         py_value = PyDict_New();
2839         if (py_value == NULL) {
2840                 PyErr_NoMemory();
2841                 talloc_free(frame);
2842                 return NULL;
2843         }
2844
2845         PyDict_SetItemString(py_value, "pwd", PyString_FromString(pwd));
2846         PyDict_SetItemString(py_value, "sid", py_sid);
2847         PyDict_SetItemString(py_value, "last_set_tim", PyInt_FromLong(last_set_time));
2848
2849         talloc_free(frame);
2850         return py_value;
2851 }
2852
2853
2854 static PyObject *py_pdb_set_trusteddom_pw(pytalloc_Object *self, PyObject *args)
2855 {
2856         TALLOC_CTX *frame = talloc_stackframe();
2857         struct pdb_methods *methods;
2858         const char *domain;
2859         const char *pwd;
2860         const struct dom_sid *domain_sid;
2861         PyObject *py_domain_sid;
2862
2863         if (!PyArg_ParseTuple(args, "ssO!:set_trusteddom_pw", &domain, &pwd,
2864                                         dom_sid_Type, &py_domain_sid)) {
2865                 talloc_free(frame);
2866                 return NULL;
2867         }
2868
2869         methods = pytalloc_get_ptr(self);
2870
2871         domain_sid = pytalloc_get_ptr(py_domain_sid);
2872
2873         if (!methods->set_trusteddom_pw(methods, domain, pwd, domain_sid)) {
2874                 PyErr_Format(py_pdb_error, "Unable to set trusted domain password");
2875                 talloc_free(frame);
2876                 return NULL;
2877         }
2878
2879         Py_RETURN_NONE;
2880         talloc_free(frame);
2881 }
2882
2883
2884 static PyObject *py_pdb_del_trusteddom_pw(pytalloc_Object *self, PyObject *args)
2885 {
2886         TALLOC_CTX *frame = talloc_stackframe();
2887         struct pdb_methods *methods;
2888         const char *domain;
2889
2890         if (!PyArg_ParseTuple(args, "s:del_trusteddom_pw", &domain)) {
2891                 talloc_free(frame);
2892                 return NULL;
2893         }
2894
2895         methods = pytalloc_get_ptr(self);
2896
2897         if (!methods->del_trusteddom_pw(methods, domain)) {
2898                 PyErr_Format(py_pdb_error, "Unable to delete trusted domain password");
2899                 talloc_free(frame);
2900                 return NULL;
2901         }
2902
2903         Py_RETURN_NONE;
2904         talloc_free(frame);
2905 }
2906
2907
2908 static PyObject *py_pdb_enum_trusteddoms(pytalloc_Object *self)
2909 {
2910         TALLOC_CTX *frame = talloc_stackframe();
2911         NTSTATUS status;
2912         struct pdb_methods *methods;
2913         uint32_t num_domains;
2914         struct trustdom_info **domains;
2915         PyObject *py_domain_list, *py_dict;
2916         int i;
2917
2918         methods = pytalloc_get_ptr(self);
2919
2920         status = methods->enum_trusteddoms(methods, frame, &num_domains, &domains);
2921         if (!NT_STATUS_IS_OK(status)) {
2922                 PyErr_Format(py_pdb_error, "Unable to enumerate trusted domains, (%d,%s)",
2923                                 NT_STATUS_V(status),
2924                                 get_friendly_nt_error_msg(status));
2925                 talloc_free(frame);
2926                 return NULL;
2927         }
2928
2929         py_domain_list = PyList_New(0);
2930         if (py_domain_list == NULL) {
2931                 PyErr_NoMemory();
2932                 talloc_free(frame);
2933                 return NULL;
2934         }
2935
2936         for(i=0; i<num_domains; i++) {
2937                 py_dict = PyDict_New();
2938                 if (py_dict) {
2939                         PyDict_SetItemString(py_dict, "name",
2940                                         PyString_FromString(domains[i]->name));
2941                         PyDict_SetItemString(py_dict, "sid",
2942                                         pytalloc_steal(dom_sid_Type, &domains[i]->sid));
2943                 }
2944
2945                 PyList_Append(py_domain_list, py_dict);
2946         }
2947
2948         talloc_free(frame);
2949         return py_domain_list;
2950 }
2951
2952
2953 static PyObject *py_pdb_get_trusted_domain(pytalloc_Object *self, PyObject *args)
2954 {
2955         TALLOC_CTX *frame = talloc_stackframe();
2956         NTSTATUS status;
2957         struct pdb_methods *methods;
2958         const char *domain;
2959         struct pdb_trusted_domain *td;
2960         PyObject *py_domain_info;
2961
2962         if (!PyArg_ParseTuple(args, "s:get_trusted_domain", &domain)) {
2963                 talloc_free(frame);
2964                 return NULL;
2965         }
2966
2967         methods = pytalloc_get_ptr(self);
2968
2969         status = methods->get_trusted_domain(methods, frame, domain, &td);
2970         if (!NT_STATUS_IS_OK(status)) {
2971                 PyErr_Format(py_pdb_error, "Unable to get trusted domain information, (%d,%s)",
2972                                 NT_STATUS_V(status),
2973                                 get_friendly_nt_error_msg(status));
2974                 talloc_free(frame);
2975                 return NULL;
2976         }
2977
2978         py_domain_info = PyDict_New();
2979         if (py_domain_info == NULL) {
2980                 PyErr_NoMemory();
2981                 talloc_free(frame);
2982                 return NULL;
2983         }
2984
2985         PyDict_SetItemString(py_domain_info, "domain_name",
2986                         PyString_FromString(td->domain_name));
2987         PyDict_SetItemString(py_domain_info, "netbios_name",
2988                         PyString_FromString(td->netbios_name));
2989         PyDict_SetItemString(py_domain_info, "security_identifier",
2990                         pytalloc_steal(dom_sid_Type, &td->security_identifier));
2991         PyDict_SetItemString(py_domain_info, "trust_auth_incoming",
2992                         PyString_FromStringAndSize((char *)td->trust_auth_incoming.data,
2993                                                 td->trust_auth_incoming.length));
2994         PyDict_SetItemString(py_domain_info, "trust_auth_outgoing",
2995                         PyString_FromStringAndSize((char *)td->trust_auth_outgoing.data,
2996                                                 td->trust_auth_outgoing.length));
2997         PyDict_SetItemString(py_domain_info, "trust_direction",
2998                         PyInt_FromLong(td->trust_direction));
2999         PyDict_SetItemString(py_domain_info, "trust_type",
3000                         PyInt_FromLong(td->trust_type));
3001         PyDict_SetItemString(py_domain_info, "trust_attributes",
3002                         PyInt_FromLong(td->trust_attributes));
3003         PyDict_SetItemString(py_domain_info, "trust_forest_trust_info",
3004                         PyString_FromStringAndSize((char *)td->trust_forest_trust_info.data,
3005                                                 td->trust_forest_trust_info.length));
3006
3007         talloc_free(frame);
3008         return py_domain_info;
3009 }
3010
3011
3012 static PyObject *py_pdb_get_trusted_domain_by_sid(pytalloc_Object *self, PyObject *args)
3013 {
3014         TALLOC_CTX *frame = talloc_stackframe();
3015         NTSTATUS status;
3016         struct pdb_methods *methods;
3017         PyObject *py_domain_sid;
3018         struct dom_sid *domain_sid;
3019         struct pdb_trusted_domain *td;
3020         PyObject *py_domain_info;
3021
3022         if (!PyArg_ParseTuple(args, "O!:get_trusted_domain_by_sid", dom_sid_Type, &py_domain_sid)) {
3023                 talloc_free(frame);
3024                 return NULL;
3025         }
3026
3027         methods = pytalloc_get_ptr(self);
3028
3029         domain_sid = pytalloc_get_ptr(py_domain_sid);
3030
3031         status = methods->get_trusted_domain_by_sid(methods, frame, domain_sid, &td);
3032         if (!NT_STATUS_IS_OK(status)) {
3033                 PyErr_Format(py_pdb_error, "Unable to get trusted domain information, (%d,%s)",
3034                                 NT_STATUS_V(status),
3035                                 get_friendly_nt_error_msg(status));
3036                 talloc_free(frame);
3037                 return NULL;
3038         }
3039
3040         py_domain_info = PyDict_New();
3041         if (py_domain_info == NULL) {
3042                 PyErr_NoMemory();
3043                 talloc_free(frame);
3044                 return NULL;
3045         }
3046
3047         PyDict_SetItemString(py_domain_info, "domain_name",
3048                         PyString_FromString(td->domain_name));
3049         PyDict_SetItemString(py_domain_info, "netbios_name",
3050                         PyString_FromString(td->netbios_name));
3051         PyDict_SetItemString(py_domain_info, "security_identifier",
3052                         pytalloc_steal(dom_sid_Type, &td->security_identifier));
3053         PyDict_SetItemString(py_domain_info, "trust_auth_incoming",
3054                         PyString_FromStringAndSize((char *)td->trust_auth_incoming.data,
3055                                                 td->trust_auth_incoming.length));
3056         PyDict_SetItemString(py_domain_info, "trust_auth_outgoing",
3057                         PyString_FromStringAndSize((char *)td->trust_auth_outgoing.data,
3058                                                 td->trust_auth_outgoing.length));
3059         PyDict_SetItemString(py_domain_info, "trust_direction",
3060                         PyInt_FromLong(td->trust_direction));
3061         PyDict_SetItemString(py_domain_info, "trust_type",
3062                         PyInt_FromLong(td->trust_type));
3063         PyDict_SetItemString(py_domain_info, "trust_attributes",
3064                         PyInt_FromLong(td->trust_attributes));
3065         PyDict_SetItemString(py_domain_info, "trust_forest_trust_info",
3066                         PyString_FromStringAndSize((char *)td->trust_forest_trust_info.data,
3067                                                 td->trust_forest_trust_info.length));
3068
3069         talloc_free(frame);
3070         return py_domain_info;
3071 }
3072
3073
3074 static PyObject *py_pdb_set_trusted_domain(pytalloc_Object *self, PyObject *args)
3075 {
3076         TALLOC_CTX *frame = talloc_stackframe();
3077         NTSTATUS status;
3078         struct pdb_methods *methods;
3079         const char *domain;
3080         PyObject *py_td_info;
3081         struct pdb_trusted_domain td_info;
3082         PyObject *py_tmp;
3083         Py_ssize_t len;
3084
3085         if (!PyArg_ParseTuple(args, "sO!:set_trusted_domain", &domain, &PyDict_Type, &py_td_info)) {
3086                 talloc_free(frame);
3087                 return NULL;
3088         }
3089
3090         py_tmp = PyDict_GetItemString(py_td_info, "domain_name");
3091         td_info.domain_name = PyString_AsString(py_tmp);
3092
3093         py_tmp = PyDict_GetItemString(py_td_info, "netbios_name");
3094         td_info.netbios_name = PyString_AsString(py_tmp);
3095
3096         py_tmp = PyDict_GetItemString(py_td_info, "security_identifier");
3097         td_info.security_identifier = *pytalloc_get_type(py_tmp, struct dom_sid);
3098
3099         py_tmp = PyDict_GetItemString(py_td_info, "trust_auth_incoming");
3100         PyString_AsStringAndSize(py_tmp, (char **)&td_info.trust_auth_incoming.data, &len);
3101         td_info.trust_auth_incoming.length = len;
3102
3103         py_tmp = PyDict_GetItemString(py_td_info, "trust_auth_outgoing");
3104         PyString_AsStringAndSize(py_tmp, (char **)&td_info.trust_auth_outgoing.data, &len);
3105         td_info.trust_auth_outgoing.length = len;
3106
3107         py_tmp = PyDict_GetItemString(py_td_info, "trust_direction");
3108         td_info.trust_direction = PyInt_AsLong(py_tmp);
3109
3110         py_tmp = PyDict_GetItemString(py_td_info, "trust_type");
3111         td_info.trust_type = PyInt_AsLong(py_tmp);
3112
3113         py_tmp = PyDict_GetItemString(py_td_info, "trust_attributes");
3114         td_info.trust_attributes = PyInt_AsLong(py_tmp);
3115
3116         py_tmp = PyDict_GetItemString(py_td_info, "trust_forest_trust_info");
3117         PyString_AsStringAndSize(py_tmp, (char **)&td_info.trust_forest_trust_info.data, &len);
3118         td_info.trust_forest_trust_info.length = len;
3119
3120         methods = pytalloc_get_ptr(self);
3121
3122         status = methods->set_trusted_domain(methods, domain, &td_info);
3123         if (!NT_STATUS_IS_OK(status)) {
3124                 PyErr_Format(py_pdb_error, "Unable to set trusted domain information, (%d,%s)",
3125                                 NT_STATUS_V(status),
3126                                 get_friendly_nt_error_msg(status));
3127                 talloc_free(frame);
3128                 return NULL;
3129         }
3130
3131         Py_RETURN_NONE;
3132         talloc_free(frame);
3133 }
3134
3135
3136 static PyObject *py_pdb_del_trusted_domain(pytalloc_Object *self, PyObject *args)
3137 {
3138         TALLOC_CTX *frame = talloc_stackframe();
3139         NTSTATUS status;
3140         struct pdb_methods *methods;
3141         const char *domain;
3142
3143         if (!PyArg_ParseTuple(args, "s:del_trusted_domain", &domain)) {
3144                 talloc_free(frame);
3145                 return NULL;
3146         }
3147
3148         methods = pytalloc_get_ptr(self);
3149
3150         status = methods->del_trusted_domain(methods, domain);
3151         if (!NT_STATUS_IS_OK(status)) {
3152                 PyErr_Format(py_pdb_error, "Unable to delete trusted domain, (%d,%s)",
3153                                 NT_STATUS_V(status),
3154                                 get_friendly_nt_error_msg(status));
3155                 talloc_free(frame);
3156                 return NULL;
3157         }
3158
3159         Py_RETURN_NONE;
3160         talloc_free(frame);
3161 }
3162
3163
3164 static PyObject *py_pdb_enum_trusted_domains(pytalloc_Object *self)
3165 {
3166         TALLOC_CTX *frame = talloc_stackframe();
3167         NTSTATUS status;
3168         struct pdb_methods *methods;
3169         uint32_t num_domains;
3170         struct pdb_trusted_domain **td_info, *td;
3171         PyObject *py_td_info, *py_domain_info;
3172         int i;
3173
3174         methods = pytalloc_get_ptr(self);
3175
3176         status = methods->enum_trusted_domains(methods, frame, &num_domains, &td_info);
3177         if (!NT_STATUS_IS_OK(status)) {
3178                 PyErr_Format(py_pdb_error, "Unable to delete trusted domain, (%d,%s)",
3179                                 NT_STATUS_V(status),
3180                                 get_friendly_nt_error_msg(status));
3181                 talloc_free(frame);
3182                 return NULL;
3183         }
3184
3185         py_td_info = PyList_New(0);
3186         if (py_td_info == NULL) {
3187                 PyErr_NoMemory();
3188                 talloc_free(frame);
3189                 return NULL;
3190         }
3191
3192         for (i=0; i<num_domains; i++) {
3193
3194                 py_domain_info = PyDict_New();
3195                 if (py_domain_info == NULL) {
3196                         PyErr_NoMemory();
3197                         Py_DECREF(py_td_info);
3198                         talloc_free(frame);
3199                         return NULL;
3200                 }
3201
3202                 td = td_info[i];
3203
3204                 PyDict_SetItemString(py_domain_info, "domain_name",
3205                                 PyString_FromString(td->domain_name));
3206                 PyDict_SetItemString(py_domain_info, "netbios_name",
3207                                 PyString_FromString(td->netbios_name));
3208                 PyDict_SetItemString(py_domain_info, "security_identifier",
3209                                 pytalloc_steal(dom_sid_Type, &td->security_identifier));
3210                 PyDict_SetItemString(py_domain_info, "trust_auth_incoming",
3211                                 PyString_FromStringAndSize((char *)td->trust_auth_incoming.data,
3212                                                         td->trust_auth_incoming.length));
3213                 PyDict_SetItemString(py_domain_info, "trust_auth_outgoing",
3214                                 PyString_FromStringAndSize((char *)td->trust_auth_outgoing.data,
3215                                                         td->trust_auth_outgoing.length));
3216                 PyDict_SetItemString(py_domain_info, "trust_direction",
3217                                 PyInt_FromLong(td->trust_direction));
3218                 PyDict_SetItemString(py_domain_info, "trust_type",
3219                                 PyInt_FromLong(td->trust_type));
3220                 PyDict_SetItemString(py_domain_info, "trust_attributes",
3221                                 PyInt_FromLong(td->trust_attributes));
3222                 PyDict_SetItemString(py_domain_info, "trust_forest_trust_info",
3223                                 PyString_FromStringAndSize((char *)td->trust_forest_trust_info.data,
3224                                                         td->trust_forest_trust_info.length));
3225                 PyList_Append(py_td_info, py_domain_info);
3226         }
3227
3228         talloc_free(frame);
3229         return py_td_info;
3230 }
3231
3232
3233 static PyObject *py_pdb_get_secret(pytalloc_Object *self, PyObject *args)
3234 {
3235         TALLOC_CTX *frame = talloc_stackframe();
3236         NTSTATUS status;
3237         struct pdb_methods *methods;
3238         const char *secret_name;
3239         DATA_BLOB secret_current, secret_old;
3240         NTTIME secret_current_lastchange, secret_old_lastchange;
3241         PyObject *py_sd;
3242         struct security_descriptor *sd;
3243         PyObject *py_secret;
3244
3245         if (!PyArg_ParseTuple(args, "s:get_secret_name", &secret_name)) {
3246                 talloc_free(frame);
3247                 return NULL;
3248         }
3249
3250         methods = pytalloc_get_ptr(self);
3251
3252         py_sd = pytalloc_new(struct security_descriptor, security_Type);
3253         if (py_sd == NULL) {
3254                 PyErr_NoMemory();
3255                 talloc_free(frame);
3256                 return NULL;
3257         }
3258         sd = pytalloc_get_ptr(py_sd);
3259
3260         status = methods->get_secret(methods, frame, secret_name,
3261                                         &secret_current,
3262                                         &secret_current_lastchange,
3263                                         &secret_old,
3264                                         &secret_old_lastchange,
3265                                         &sd);
3266         if (!NT_STATUS_IS_OK(status)) {
3267                 PyErr_Format(py_pdb_error, "Unable to get information for secret (%s), (%d,%s)",
3268                                 secret_name,
3269                                 NT_STATUS_V(status),
3270                                 get_friendly_nt_error_msg(status));
3271                 talloc_free(frame);
3272                 return NULL;
3273         }
3274
3275         py_secret = PyDict_New();
3276         if (py_secret == NULL) {
3277                 PyErr_NoMemory();
3278                 Py_DECREF(py_sd);
3279                 talloc_free(frame);
3280                 return NULL;
3281         }
3282
3283         PyDict_SetItemString(py_secret, "secret_current",
3284                         PyString_FromStringAndSize((char *)secret_current.data, secret_current.length));
3285         PyDict_SetItemString(py_secret, "secret_current_lastchange",
3286                         PyLong_FromUnsignedLongLong(secret_current_lastchange));
3287         PyDict_SetItemString(py_secret, "secret_old",
3288                         PyString_FromStringAndSize((char *)secret_old.data, secret_old.length));
3289         PyDict_SetItemString(py_secret, "secret_old_lastchange",
3290                         PyLong_FromUnsignedLongLong(secret_old_lastchange));
3291         PyDict_SetItemString(py_secret, "sd", py_sd);
3292
3293         talloc_free(frame);
3294         return py_secret;
3295 }
3296
3297
3298 static PyObject *py_pdb_set_secret(pytalloc_Object *self, PyObject *args)
3299 {
3300         TALLOC_CTX *frame = talloc_stackframe();
3301         NTSTATUS status;
3302         struct pdb_methods *methods;
3303         const char *secret_name;
3304         PyObject *py_secret;
3305         PyObject *py_secret_cur, *py_secret_old, *py_sd;
3306         DATA_BLOB secret_current, secret_old;
3307         struct security_descriptor *sd;
3308         Py_ssize_t len;
3309
3310         if (!PyArg_ParseTuple(args, "sO!:set_secret_name", &secret_name, PyDict_Type, &py_secret)) {
3311                 talloc_free(frame);
3312                 return NULL;
3313         }
3314
3315         py_secret_cur = PyDict_GetItemString(py_secret, "secret_current");
3316         py_secret_old = PyDict_GetItemString(py_secret, "secret_old");
3317         py_sd = PyDict_GetItemString(py_secret, "sd");
3318
3319         PY_CHECK_TYPE(&PyString_Type, py_secret_cur, return NULL;);
3320         PY_CHECK_TYPE(&PyString_Type, py_secret_old, return NULL;);
3321         PY_CHECK_TYPE(security_Type, py_sd, return NULL;);
3322
3323         methods = pytalloc_get_ptr(self);
3324
3325         PyString_AsStringAndSize(py_secret_cur, (char **)&secret_current.data, &len);
3326         secret_current.length = len;
3327         PyString_AsStringAndSize(py_secret_old, (char **)&secret_old.data, &len);
3328         secret_current.length = len;
3329         sd = pytalloc_get_ptr(py_sd);
3330
3331         status = methods->set_secret(methods, secret_name, &secret_current, &secret_old, sd);
3332         if (!NT_STATUS_IS_OK(status)) {
3333                 PyErr_Format(py_pdb_error, "Unable to set information for secret (%s), (%d,%s)",
3334                                 secret_name,
3335                                 NT_STATUS_V(status),
3336                                 get_friendly_nt_error_msg(status));
3337                 talloc_free(frame);
3338                 return NULL;
3339         }
3340
3341         Py_RETURN_NONE;
3342         talloc_free(frame);
3343 }
3344
3345
3346 static PyObject *py_pdb_delete_secret(pytalloc_Object *self, PyObject *args)
3347 {
3348         TALLOC_CTX *frame = talloc_stackframe();
3349         NTSTATUS status;
3350         struct pdb_methods *methods;
3351         const char *secret_name;
3352
3353         if (!PyArg_ParseTuple(args, "s:delete_secret", &secret_name)) {
3354                 talloc_free(frame);
3355                 return NULL;
3356         }
3357
3358         methods = pytalloc_get_ptr(self);
3359
3360         status = methods->delete_secret(methods, secret_name);
3361         if (!NT_STATUS_IS_OK(status)) {
3362                 PyErr_Format(py_pdb_error, "Unable to delete secret (%s), (%d,%s)",
3363                                 secret_name,
3364                                 NT_STATUS_V(status),
3365                                 get_friendly_nt_error_msg(status));
3366                 talloc_free(frame);
3367                 return NULL;
3368         }
3369
3370         Py_RETURN_NONE;
3371         talloc_free(frame);
3372 }
3373
3374 static PyMethodDef py_pdb_methods[] = {
3375         { "domain_info", (PyCFunction)py_pdb_domain_info, METH_NOARGS,
3376                 "domain_info() -> str\n\n \
3377                 Get domain information for the database." },
3378         { "getsampwnam", (PyCFunction)py_pdb_getsampwnam, METH_VARARGS,
3379                 "getsampwnam(username) -> samu object\n\n \
3380                 Get user information by name." },
3381         { "getsampwsid", (PyCFunction)py_pdb_getsampwsid, METH_VARARGS,
3382                 "getsampwsid(user_sid) -> samu object\n\n \
3383                 Get user information by sid (dcerpc.security.dom_sid object)." },
3384         { "create_user", (PyCFunction)py_pdb_create_user, METH_VARARGS,
3385                 "create_user(username, acct_flags) -> rid\n\n \
3386                 Create user. acct_flags are samr account control flags." },
3387         { "delete_user", (PyCFunction)py_pdb_delete_user, METH_VARARGS,
3388                 "delete_user(samu object) -> None\n\n \
3389                 Delete user." },
3390         { "add_sam_account", (PyCFunction)py_pdb_add_sam_account, METH_VARARGS,
3391                 "add_sam_account(samu object) -> None\n\n \
3392                 Add SAM account." },
3393         { "update_sam_account", (PyCFunction)py_pdb_update_sam_account, METH_VARARGS,
3394                 "update_sam_account(samu object) -> None\n\n \
3395                 Update SAM account." },
3396         { "delete_sam_account", (PyCFunction)py_pdb_delete_sam_account, METH_VARARGS,
3397                 "delete_sam_account(samu object) -> None\n\n \
3398                 Delete SAM account." },
3399         { "rename_sam_account", (PyCFunction)py_pdb_rename_sam_account, METH_VARARGS,
3400                 "rename_sam_account(samu object1, new_username) -> None\n\n \
3401                 Rename SAM account." },
3402         /* update_login_attempts */
3403         { "getgrsid", (PyCFunction)py_pdb_getgrsid, METH_VARARGS,
3404                 "getgrsid(group_sid) -> groupmap object\n\n \
3405                 Get group information by sid (dcerpc.security.dom_sid object)." },
3406         { "getgrgid", (PyCFunction)py_pdb_getgrgid, METH_VARARGS,
3407                 "getgrsid(gid) -> groupmap object\n\n \
3408                 Get group information by gid." },
3409         { "getgrnam", (PyCFunction)py_pdb_getgrnam, METH_VARARGS,
3410                 "getgrsid(groupname) -> groupmap object\n\n \
3411                 Get group information by name." },
3412         { "create_dom_group", (PyCFunction)py_pdb_create_dom_group, METH_VARARGS,
3413                 "create_dom_group(groupname) -> group_rid\n\n \
3414                 Create new domain group by name." },
3415         { "delete_dom_group", (PyCFunction)py_pdb_delete_dom_group, METH_VARARGS,
3416                 "delete_dom_group(group_rid) -> None\n\n \
3417                 Delete domain group identified by rid" },
3418         { "add_group_mapping_entry", (PyCFunction)py_pdb_add_group_mapping_entry, METH_VARARGS,
3419                 "add_group_mapping_entry(groupmap) -> None\n \
3420                 Add group mapping entry for groupmap object." },
3421         { "update_group_mapping_entry", (PyCFunction)py_pdb_update_group_mapping_entry, METH_VARARGS,
3422                 "update_group_mapping_entry(groupmap) -> None\n\n \
3423                 Update group mapping entry for groupmap object." },
3424         { "delete_group_mapping_entry", (PyCFunction)py_pdb_delete_group_mapping_entry, METH_VARARGS,
3425                 "delete_group_mapping_entry(groupmap) -> None\n\n \
3426                 Delete group mapping entry for groupmap object." },
3427         { "enum_group_mapping", (PyCFunction)py_pdb_enum_group_mapping, METH_VARARGS,
3428                 "enum_group_mapping([domain_sid, [type, [unix_only]]]) -> List\n\n \
3429                 Return list of group mappings as groupmap objects. Optional arguments are domain_sid object, type of group, unix only flag." },
3430         { "enum_group_members", (PyCFunction)py_pdb_enum_group_members, METH_VARARGS,
3431                 "enum_group_members(group_sid) -> List\n\n \
3432                 Return list of users (dom_sid object) in group." },
3433         { "enum_group_memberships", (PyCFunction)py_pdb_enum_group_memberships, METH_VARARGS,
3434                 "enum_group_memberships(samu object) -> List\n\n \
3435                 Return list of groups (dom_sid object) this user is part of." },
3436         /* set_unix_primary_group */
3437         { "add_groupmem", (PyCFunction)py_pdb_add_groupmem, METH_VARARGS,
3438                 "add_groupmem(group_rid, member_rid) -> None\n\n \
3439                 Add user to group." },
3440         { "del_groupmem", (PyCFunction)py_pdb_del_groupmem, METH_VARARGS,
3441                 "del_groupmem(group_rid, member_rid) -> None\n\n \
3442                 Remove user from from group." },
3443         { "create_alias", (PyCFunction)py_pdb_create_alias, METH_VARARGS,
3444                 "create_alias(alias_name) -> alias_rid\n\n \
3445                 Create alias entry." },
3446         { "delete_alias", (PyCFunction)py_pdb_delete_alias, METH_VARARGS,
3447                 "delete_alias(alias_sid) -> None\n\n \
3448                 Delete alias entry." },
3449         { "get_aliasinfo", (PyCFunction)py_pdb_get_aliasinfo, METH_VARARGS,
3450                 "get_aliasinfo(alias_sid) -> Mapping\n\n \
3451                 Get alias information as a dictionary with keys - acct_name, acct_desc, rid." },
3452         { "set_aliasinfo", (PyCFunction)py_pdb_set_aliasinfo, METH_VARARGS,
3453                 "set_alias_info(alias_sid, Mapping) -> None\n\n \
3454                 Set alias information from a dictionary with keys - acct_name, acct_desc." },
3455         { "add_aliasmem", (PyCFunction)py_pdb_add_aliasmem, METH_VARARGS,
3456                 "add_aliasmem(alias_sid, member_sid) -> None\n\n \
3457                 Add user to alias entry." },
3458         { "del_aliasmem", (PyCFunction)py_pdb_del_aliasmem, METH_VARARGS,
3459                 "del_aliasmem(alias_sid, member_sid) -> None\n\n \
3460                 Remove a user from alias entry." },
3461         { "enum_aliasmem", (PyCFunction)py_pdb_enum_aliasmem, METH_VARARGS,
3462                 "enum_aliasmem(alias_sid) -> List\n\n \
3463                 Return a list of members (dom_sid object) for alias entry." },
3464         /* enum_alias_memberships */
3465         /* lookup_rids */
3466         /* lookup_names */
3467         { "get_account_policy", (PyCFunction)py_pdb_get_account_policy, METH_NOARGS,
3468                 "get_account_policy() -> Mapping\n\n \
3469                 Get account policy information as a dictionary." },
3470         { "set_account_policy", (PyCFunction)py_pdb_set_account_policy, METH_VARARGS,
3471                 "get_account_policy(Mapping) -> None\n\n \
3472                 Set account policy settings from a dicionary." },
3473         /* get_seq_num */
3474         { "search_users", (PyCFunction)py_pdb_search_users, METH_VARARGS,
3475                 "search_users(acct_flags) -> List\n\n \
3476                 Search users. acct_flags are samr account control flags.\n \
3477                 Each list entry is dictionary with keys - idx, rid, acct_flags, account_name, fullname, description." },
3478         { "search_groups", (PyCFunction)py_pdb_search_groups, METH_NOARGS,
3479                 "search_groups() -> List\n\n \
3480                 Search unix only groups. \n \
3481                 Each list entry is dictionary with keys - idx, rid, acct_flags, account_name, fullname, description." },
3482         { "search_aliases", (PyCFunction)py_pdb_search_aliases, METH_VARARGS,
3483                 "search_aliases([domain_sid]) -> List\n\n \
3484                 Search aliases. domain_sid is dcerpc.security.dom_sid object.\n \
3485                 Each list entry is dictionary with keys - idx, rid, acct_flags, account_name, fullname, description." },
3486         { "uid_to_sid", (PyCFunction)py_pdb_uid_to_sid, METH_VARARGS,
3487                 "uid_to_sid(uid) -> sid\n\n \
3488                 Return sid for given user id." },
3489         { "gid_to_sid", (PyCFunction)py_pdb_gid_to_sid, METH_VARARGS,
3490                 "gid_to_sid(gid) -> sid\n\n \
3491                 Return sid for given group id." },
3492         { "sid_to_id", (PyCFunction)py_pdb_sid_to_id, METH_VARARGS,
3493                 "sid_to_id(sid) -> Tuple\n\n \
3494                 Return id and type for given sid." },
3495         /* capabilities */
3496         { "new_rid", (PyCFunction)py_pdb_new_rid, METH_NOARGS,
3497                 "new_rid() -> rid\n\n \
3498                 Get a new rid." },
3499         { "get_trusteddom_pw", (PyCFunction)py_pdb_get_trusteddom_pw, METH_VARARGS,
3500                 "get_trusteddom_pw(domain) -> Mapping\n\n \
3501                 Get trusted domain password, sid and last set time in a dictionary." },
3502         { "set_trusteddom_pw", (PyCFunction)py_pdb_set_trusteddom_pw, METH_VARARGS,
3503                 "set_trusteddom_pw(domain, pwd, sid) -> None\n\n \
3504                 Set trusted domain password." },
3505         { "del_trusteddom_pw", (PyCFunction)py_pdb_del_trusteddom_pw, METH_VARARGS,
3506                 "del_trusteddom_pw(domain) -> None\n\n \
3507                 Delete trusted domain password." },
3508         { "enum_trusteddoms", (PyCFunction)py_pdb_enum_trusteddoms, METH_NOARGS,
3509                 "enum_trusteddoms() -> List\n\n \
3510                 Get list of trusted domains. Each item is a dictionary with name and sid keys" },
3511         { "get_trusted_domain", (PyCFunction)py_pdb_get_trusted_domain, METH_VARARGS,
3512                 "get_trusted_domain(domain) -> Mapping\n\n \
3513                 Get trusted domain information by name. Information is a dictionary with keys - domain_name, netbios_name, security_identifier, trust_auth_incoming, trust_auth_outgoing, trust_direction, trust_type, trust_attributes, trust_forest_trust_info." },
3514         { "get_trusted_domain_by_sid", (PyCFunction)py_pdb_get_trusted_domain_by_sid, METH_VARARGS,
3515                 "get_trusted_domain_by_sid(domain_sid) -> Mapping\n\n \
3516                 Get trusted domain information by sid. Information is a dictionary with keys - domain_name, netbios_name, security_identifier, trust_auth_incoming, trust_auth_outgoing, trust_direction, trust_type, trust_attributes, trust_forest_trust_info" },
3517         { "set_trusted_domain", (PyCFunction)py_pdb_set_trusted_domain, METH_VARARGS,
3518                 "set_trusted_domain(domain, Mapping) -> None\n\n \
3519                 Set trusted domain information for domain. Mapping is a dictionary with keys - domain_name, netbios_name, security_identifier, trust_auth_incoming, trust_auth_outgoing, trust_direction, trust_type, trust_attributes, trust_forest_trust_info." },
3520         { "del_trusted_domain", (PyCFunction)py_pdb_del_trusted_domain, METH_VARARGS,
3521                 "del_trusted_domain(domain) -> None\n\n \
3522                 Delete trusted domain." },
3523         { "enum_trusted_domains", (PyCFunction)py_pdb_enum_trusted_domains, METH_VARARGS,
3524                 "enum_trusted_domains() -> List\n\n \
3525                 Get list of trusted domains. Each entry is a dictionary with keys - domain_name, netbios_name, security_identifier, trust_auth_incoming, trust_auth_outgoing, trust_direction, trust_type, trust_attributes, trust_forest_trust_info." },
3526         { "get_secret", (PyCFunction)py_pdb_get_secret, METH_VARARGS,
3527                 "get_secret(secret_name) -> Mapping\n\n \
3528                 Get secret information for secret_name. Information is a dictionary with keys - secret_current, secret_current_lastchange, secret_old, secret_old_lastchange, sd." },
3529         { "set_secret", (PyCFunction)py_pdb_set_secret, METH_VARARGS,
3530                 "set_secret(secret_name, Mapping) -> None\n\n \
3531                 Set secret information for secret_name using dictionary with keys - secret_current, sd." },
3532         { "delete_secret", (PyCFunction)py_pdb_delete_secret, METH_VARARGS,
3533                 "delete_secret(secret_name) -> None\n\n \
3534                 Delete secret information for secret_name." },
3535         { NULL },
3536 };
3537
3538
3539 static PyObject *py_pdb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3540 {
3541         TALLOC_CTX *frame = talloc_stackframe();
3542         const char *url = NULL;
3543         PyObject *pypdb;
3544         NTSTATUS status;
3545         struct pdb_methods *methods;
3546
3547         if (!PyArg_ParseTuple(args, "s", &url)) {
3548                 talloc_free(frame);
3549                 return NULL;
3550         }
3551
3552         /* Initalize list of methods */
3553         status = make_pdb_method_name(&methods, url);
3554         if (!NT_STATUS_IS_OK(status)) {
3555                 PyErr_Format(py_pdb_error, "Cannot load backend methods for '%s' backend (%d,%s)",
3556                                 url,
3557                                 NT_STATUS_V(status),
3558                                 get_friendly_nt_error_msg(status));
3559                 talloc_free(frame);
3560                 return NULL;
3561         }
3562
3563         if ((pypdb = pytalloc_steal(type, methods)) == NULL) {
3564                 PyErr_NoMemory();
3565                 talloc_free(frame);
3566                 return NULL;
3567         }
3568
3569         talloc_free(frame);
3570         return pypdb;
3571 }
3572
3573
3574 static PyTypeObject PyPDB = {
3575         .tp_name = "passdb.PDB",
3576         .tp_basicsize = sizeof(pytalloc_Object),
3577         .tp_new = py_pdb_new,
3578         .tp_flags = Py_TPFLAGS_DEFAULT,
3579         .tp_methods = py_pdb_methods,
3580         .tp_doc = "PDB(url[, read_write_flags]) -> Password DB object\n",
3581 };
3582
3583
3584 /*
3585  * Return a list of passdb backends
3586  */
3587 static PyObject *py_passdb_backends(PyObject *self)
3588 {
3589         TALLOC_CTX *frame = talloc_stackframe();
3590         PyObject *py_blist;
3591         const struct pdb_init_function_entry *entry;
3592
3593         entry = pdb_get_backends();
3594         if(! entry) {
3595                 Py_RETURN_NONE;
3596         }
3597
3598         if((py_blist = PyList_New(0)) == NULL) {
3599                 PyErr_NoMemory();
3600                 talloc_free(frame);
3601                 return NULL;
3602         }
3603
3604         while(entry) {
3605                 PyList_Append(py_blist, PyString_FromString(entry->name));
3606                 entry = entry->next;
3607         }
3608
3609         talloc_free(frame);
3610         return py_blist;
3611 }
3612
3613
3614 static PyObject *py_set_smb_config(PyObject *self, PyObject *args)
3615 {
3616         TALLOC_CTX *frame = talloc_stackframe();
3617         const char *smb_config;
3618
3619         if (!PyArg_ParseTuple(args, "s", &smb_config)) {
3620                 talloc_free(frame);
3621                 return NULL;
3622         }
3623
3624         /* Load smbconf parameters */
3625         if (!lp_load_global(smb_config)) {
3626                 PyErr_Format(py_pdb_error, "Cannot open '%s'", smb_config);
3627                 talloc_free(frame);
3628                 return NULL;
3629         }
3630
3631         Py_RETURN_NONE;
3632         talloc_free(frame);
3633 }
3634
3635
3636 static PyObject *py_set_secrets_dir(PyObject *self, PyObject *args)
3637 {
3638         TALLOC_CTX *frame = talloc_stackframe();
3639         const char *private_dir;
3640
3641         if (!PyArg_ParseTuple(args, "s", &private_dir)) {
3642                 talloc_free(frame);
3643                 return NULL;
3644         }
3645
3646         /* Initialize secrets database */
3647         if (!secrets_init_path(private_dir, lp_use_ntdb())) {
3648                 PyErr_Format(py_pdb_error, "Cannot open secrets file database in '%s'",
3649                                 private_dir);
3650                 talloc_free(frame);
3651                 return NULL;
3652         }
3653
3654         talloc_free(frame);
3655         Py_RETURN_NONE;
3656 }
3657
3658 static PyObject *py_reload_static_pdb(PyObject *self, PyObject *args)
3659 {
3660         TALLOC_CTX *frame = talloc_stackframe();
3661
3662         /* Initialize secrets database */
3663         if (!initialize_password_db(true, NULL)) {
3664                 PyErr_Format(py_pdb_error, "Cannot re-open passdb backend %s", lp_passdb_backend());
3665                 talloc_free(frame);
3666                 return NULL;
3667         }
3668
3669         talloc_free(frame);
3670         Py_RETURN_NONE;
3671 }
3672
3673 static PyObject *py_get_global_sam_sid(PyObject *self)
3674 {
3675         TALLOC_CTX *frame = talloc_stackframe();
3676         struct dom_sid *domain_sid, *domain_sid_copy;
3677         PyObject *py_dom_sid;
3678
3679         domain_sid = get_global_sam_sid();
3680
3681         domain_sid_copy = dom_sid_dup(frame, domain_sid);
3682         if (domain_sid_copy == NULL) {
3683                 PyErr_NoMemory();
3684                 talloc_free(frame);
3685                 return NULL;
3686         }
3687
3688         py_dom_sid = pytalloc_steal(dom_sid_Type, domain_sid_copy);
3689
3690         talloc_free(frame);
3691         return py_dom_sid;
3692 }
3693
3694
3695 static PyMethodDef py_passdb_methods[] = {
3696         { "get_backends", (PyCFunction)py_passdb_backends, METH_NOARGS,
3697                 "get_backends() -> list\n\n \
3698                 Get a list of password database backends supported." },
3699         { "set_smb_config", (PyCFunction)py_set_smb_config, METH_VARARGS,
3700                 "set_smb_config(path) -> None\n\n \
3701                 Set path to smb.conf file to load configuration parameters." },
3702         { "set_secrets_dir", (PyCFunction)py_set_secrets_dir, METH_VARARGS,
3703                 "set_secrets_dir(private_dir) -> None\n\n \
3704                 Set path to private directory to load secrets database from non-default location." },
3705         { "get_global_sam_sid", (PyCFunction)py_get_global_sam_sid, METH_NOARGS,
3706                 "get_global_sam_sid() -> dom_sid\n\n \
3707                 Return domain SID." },
3708         { "reload_static_pdb", (PyCFunction)py_reload_static_pdb, METH_NOARGS,
3709                 "reload_static_pdb() -> None\n\n \
3710                 Re-initalise the static pdb used internally.  Needed if 'passdb backend' is changed." },
3711         { NULL },
3712 };
3713
3714 void initpassdb(void)
3715 {
3716         TALLOC_CTX *frame = talloc_stackframe();
3717         PyObject *m, *mod;
3718         char exception_name[] = "passdb.error";
3719
3720         PyTypeObject *talloc_type = pytalloc_GetObjectType();
3721         if (talloc_type == NULL) {
3722                 talloc_free(frame);
3723                 return;
3724         }
3725
3726         PyPDB.tp_base = talloc_type;
3727         if (PyType_Ready(&PyPDB) < 0) {
3728                 talloc_free(frame);
3729                 return;
3730         }
3731
3732         PySamu.tp_base = talloc_type;
3733         if (PyType_Ready(&PySamu) < 0) {
3734                 talloc_free(frame);
3735                 return;
3736         }
3737
3738         PyGroupmap.tp_base = talloc_type;
3739         if (PyType_Ready(&PyGroupmap) < 0) {
3740                 talloc_free(frame);
3741                 return;
3742         }
3743
3744         m = Py_InitModule3("passdb", py_passdb_methods, "SAMBA Password Database");
3745         if (m == NULL) {
3746             talloc_free(frame);
3747             return;
3748         }
3749
3750         /* Create new exception for passdb module */
3751         py_pdb_error = PyErr_NewException(exception_name, NULL, NULL);
3752         Py_INCREF(py_pdb_error);
3753         PyModule_AddObject(m, "error", py_pdb_error);
3754
3755         Py_INCREF(&PyPDB);
3756         PyModule_AddObject(m, "PDB", (PyObject *)&PyPDB);
3757
3758         Py_INCREF(&PySamu);
3759         PyModule_AddObject(m, "Samu", (PyObject *)&PySamu);
3760
3761         Py_INCREF(&PyGroupmap);
3762         PyModule_AddObject(m, "Groupmap", (PyObject *)&PyGroupmap);
3763
3764         /* Import dom_sid type from dcerpc.security */
3765         mod = PyImport_ImportModule("samba.dcerpc.security");
3766         if (mod == NULL) {
3767                 talloc_free(frame);
3768                 return;
3769         }
3770
3771         dom_sid_Type = (PyTypeObject *)PyObject_GetAttrString(mod, "dom_sid");
3772         if (dom_sid_Type == NULL) {
3773                 talloc_free(frame);
3774                 return;
3775         }
3776
3777         /* Import security_descriptor type from dcerpc.security */
3778         security_Type = (PyTypeObject *)PyObject_GetAttrString(mod, "descriptor");
3779         Py_DECREF(mod);
3780         if (security_Type == NULL) {
3781                 talloc_free(frame);
3782                 return;
3783         }
3784
3785         /* Import GUID type from dcerpc.misc */
3786         mod = PyImport_ImportModule("samba.dcerpc.misc");
3787         if (mod == NULL) {
3788                 talloc_free(frame);
3789                 return;
3790         }
3791
3792         guid_Type = (PyTypeObject *)PyObject_GetAttrString(mod, "GUID");
3793         Py_DECREF(mod);
3794         if (guid_Type == NULL) {
3795                 talloc_free(frame);
3796                 return;
3797         }
3798         talloc_free(frame);
3799 }