passdb: Added python wrapper to passdb
[idra/samba.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 "passdb.h"
26 #include "secrets.h"
27
28 #ifndef Py_RETURN_NONE
29 #define Py_RETURN_NONE  return Py_INCREF(Py_None), Py_None
30 #endif
31
32 #ifndef PY_CHECK_TYPE
33 #define PY_CHECK_TYPE(type, var, fail) \
34         if (!PyObject_TypeCheck(var, type)) {\
35                 PyErr_Format(PyExc_TypeError, __location__ ": Expected type '%s' for '%s' of type '%s'", (type)->tp_name, #var, Py_TYPE(var)->tp_name); \
36                 fail; \
37         }
38 #endif
39
40
41 static PyTypeObject *dom_sid_Type = NULL;
42
43 staticforward PyTypeObject PySamu;
44 staticforward PyTypeObject PyPDB;
45
46 static PyObject *py_pdb_error;
47
48 void initpassdb(void);
49
50
51 /************************** PIDL Autogeneratd ******************************/
52
53 static PyObject *py_samu_get_logon_time(PyObject *obj, void *closure)
54 {
55         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
56         PyObject *py_logon_time;
57
58         py_logon_time = PyInt_FromLong(pdb_get_logon_time(sam_acct));
59         return py_logon_time;
60 }
61
62 static int py_samu_set_logon_time(PyObject *obj, PyObject *value, void *closure)
63 {
64         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
65
66         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
67         if (!pdb_set_logon_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
68                 return -1;
69         }
70         return 0;
71 }
72
73 static PyObject *py_samu_get_logoff_time(PyObject *obj, void *closure)
74 {
75         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
76         PyObject *py_logoff_time;
77
78         py_logoff_time = PyInt_FromLong(pdb_get_logoff_time(sam_acct));
79         return py_logoff_time;
80 }
81
82 static int py_samu_set_logoff_time(PyObject *obj, PyObject *value, void *closure)
83 {
84         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
85
86         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
87         if (!pdb_set_logoff_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
88                 return -1;
89         }
90         return 0;
91 }
92
93 static PyObject *py_samu_get_kickoff_time(PyObject *obj, void *closure)
94 {
95         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
96         PyObject *py_kickoff_time;
97
98         py_kickoff_time = PyInt_FromLong(pdb_get_kickoff_time(sam_acct));
99         return py_kickoff_time;
100 }
101
102 static int py_samu_set_kickoff_time(PyObject *obj, PyObject *value, void *closure)
103 {
104         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
105
106         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
107         if (!pdb_set_kickoff_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
108                 return -1;
109         }
110         return 0;
111 }
112
113 static PyObject *py_samu_get_bad_password_time(PyObject *obj, void *closure)
114 {
115         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
116         PyObject *py_bad_password_time;
117
118         py_bad_password_time = PyInt_FromLong(pdb_get_bad_password_time(sam_acct));
119         return py_bad_password_time;
120 }
121
122 static int py_samu_set_bad_password_time(PyObject *obj, PyObject *value, void *closure)
123 {
124         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
125
126         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
127         if (!pdb_set_bad_password_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
128                 return -1;
129         }
130         return 0;
131 }
132
133 static PyObject *py_samu_get_pass_last_set_time(PyObject *obj, void *closure)
134 {
135         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
136         PyObject *py_pass_last_set_time;
137
138         py_pass_last_set_time = PyInt_FromLong(pdb_get_pass_last_set_time(sam_acct));
139         return py_pass_last_set_time;
140 }
141
142 static int py_samu_set_pass_last_set_time(PyObject *obj, PyObject *value, void *closure)
143 {
144         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
145
146         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
147         if (!pdb_set_pass_last_set_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
148                 return -1;
149         }
150         return 0;
151 }
152
153 static PyObject *py_samu_get_pass_can_change_time(PyObject *obj, void *closure)
154 {
155         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
156         PyObject *py_pass_can_change_time;
157
158         py_pass_can_change_time = PyInt_FromLong(pdb_get_pass_can_change_time(sam_acct));
159         return py_pass_can_change_time;
160 }
161
162 static int py_samu_set_pass_can_change_time(PyObject *obj, PyObject *value, void *closure)
163 {
164         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
165
166         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
167         if (!pdb_set_pass_can_change_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
168                 return -1;
169         }
170         return 0;
171 }
172
173 static PyObject *py_samu_get_pass_must_change_time(PyObject *obj, void *closure)
174 {
175         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
176         PyObject *py_pass_must_change_time;
177
178         py_pass_must_change_time = PyInt_FromLong(pdb_get_pass_must_change_time(sam_acct));
179         return py_pass_must_change_time;
180 }
181
182 static int py_samu_set_pass_must_change_time(PyObject *obj, PyObject *value, void *closure)
183 {
184         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
185
186         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
187         if (!pdb_set_pass_must_change_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
188                 return -1;
189         }
190         return 0;
191 }
192
193 static PyObject *py_samu_get_username(PyObject *obj, void *closure)
194 {
195         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
196         PyObject *py_username;
197         const char *username;
198
199         username = pdb_get_username(sam_acct);
200         if (username == NULL) {
201                 Py_RETURN_NONE;
202         }
203
204         py_username = PyString_FromString(username);
205         return py_username;
206 }
207
208 static int py_samu_set_username(PyObject *obj, PyObject *value, void *closure)
209 {
210         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
211
212         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
213         if (!pdb_set_username(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
214                 return -1;
215         }
216         return 0;
217 }
218
219 static PyObject *py_samu_get_domain(PyObject *obj, void *closure)
220 {
221         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
222         PyObject *py_domain;
223         const char *domain;
224
225         domain = pdb_get_domain(sam_acct);
226         if (domain == NULL) {
227                 Py_RETURN_NONE;
228         }
229
230         py_domain = PyString_FromString(domain);
231         return py_domain;
232 }
233
234 static int py_samu_set_domain(PyObject *obj, PyObject *value, void *closure)
235 {
236         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
237
238         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
239         if (!pdb_set_domain(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
240                 return -1;
241         }
242         return 0;
243 }
244
245 static PyObject *py_samu_get_nt_username(PyObject *obj, void *closure)
246 {
247         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
248         PyObject *py_nt_username;
249         const char *nt_username;
250
251         nt_username = pdb_get_nt_username(sam_acct);
252         if (nt_username == NULL) {
253                 Py_RETURN_NONE;
254         }
255
256         py_nt_username = PyString_FromString(nt_username);
257         return py_nt_username;
258 }
259
260 static int py_samu_set_nt_username(PyObject *obj, PyObject *value, void *closure)
261 {
262         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
263
264         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
265         if (!pdb_set_nt_username(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
266                 return -1;
267         }
268         return 0;
269 }
270
271 static PyObject *py_samu_get_full_name(PyObject *obj, void *closure)
272 {
273         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
274         PyObject *py_full_name;
275         const char *full_name;
276
277         full_name = pdb_get_fullname(sam_acct);
278         if (full_name == NULL) {
279                 Py_RETURN_NONE;
280         }
281
282         py_full_name = PyString_FromString(full_name);
283         return py_full_name;
284 }
285
286 static int py_samu_set_full_name(PyObject *obj, PyObject *value, void *closure)
287 {
288         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
289
290         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
291         if (!pdb_set_fullname(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
292                 return -1;
293         }
294         return 0;
295 }
296
297 static PyObject *py_samu_get_home_dir(PyObject *obj, void *closure)
298 {
299         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
300         PyObject *py_home_dir;
301         const char *home_dir;
302
303         home_dir = pdb_get_homedir(sam_acct);
304         if (home_dir == NULL) {
305                 Py_RETURN_NONE;
306         }
307
308         py_home_dir = PyString_FromString(home_dir);
309         return py_home_dir;
310 }
311
312 static int py_samu_set_home_dir(PyObject *obj, PyObject *value, void *closure)
313 {
314         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
315
316         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
317         if (!pdb_set_homedir(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
318                 return -1;
319         }
320         return 0;
321 }
322
323 static PyObject *py_samu_get_dir_drive(PyObject *obj, void *closure)
324 {
325         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
326         PyObject *py_dir_drive;
327         const char *dir_drive;
328
329         dir_drive = pdb_get_dir_drive(sam_acct);
330         if (dir_drive == NULL) {
331                 Py_RETURN_NONE;
332         }
333
334         py_dir_drive = PyString_FromString(dir_drive);
335         return py_dir_drive;
336 }
337
338 static int py_samu_set_dir_drive(PyObject *obj, PyObject *value, void *closure)
339 {
340         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
341
342         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
343         if (!pdb_set_dir_drive(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
344                 return -1;
345         }
346         return 0;
347 }
348
349 static PyObject *py_samu_get_logon_script(PyObject *obj, void *closure)
350 {
351         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
352         PyObject *py_logon_script;
353         const char *logon_script;
354
355         logon_script = pdb_get_logon_script(sam_acct);
356         if (logon_script == NULL) {
357                 Py_RETURN_NONE;
358         }
359
360         py_logon_script = PyString_FromString(logon_script);
361         return py_logon_script;
362 }
363
364 static int py_samu_set_logon_script(PyObject *obj, PyObject *value, void *closure)
365 {
366         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
367
368         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
369         if (!pdb_set_logon_script(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
370                 return -1;
371         }
372         return 0;
373 }
374
375 static PyObject *py_samu_get_profile_path(PyObject *obj, void *closure)
376 {
377         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
378         PyObject *py_profile_path;
379         const char *profile_path;
380
381         profile_path = pdb_get_profile_path(sam_acct);
382         if (profile_path == NULL) {
383                 Py_RETURN_NONE;
384         }
385
386         py_profile_path = PyString_FromString(profile_path);
387         return py_profile_path;
388 }
389
390 static int py_samu_set_profile_path(PyObject *obj, PyObject *value, void *closure)
391 {
392         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
393
394         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
395         if (!pdb_set_profile_path(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
396                 return -1;
397         }
398         return 0;
399 }
400
401 static PyObject *py_samu_get_acct_desc(PyObject *obj, void *closure)
402 {
403         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
404         PyObject *py_acct_desc;
405         const char *acct_desc;
406
407         acct_desc = pdb_get_acct_desc(sam_acct);
408         if (acct_desc == NULL) {
409                 Py_RETURN_NONE;
410         }
411
412         py_acct_desc = PyString_FromString(acct_desc);
413         return py_acct_desc;
414 }
415
416 static int py_samu_set_acct_desc(PyObject *obj, PyObject *value, void *closure)
417 {
418         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
419
420         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
421         if (!pdb_set_acct_desc(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
422                 return -1;
423         }
424         return 0;
425 }
426
427 static PyObject *py_samu_get_workstations(PyObject *obj, void *closure)
428 {
429         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
430         PyObject *py_workstations;
431         const char *workstations;
432
433         workstations = pdb_get_workstations(sam_acct);
434         if (workstations == NULL) {
435                 Py_RETURN_NONE;
436         }
437
438         py_workstations = PyString_FromString(workstations);
439         return py_workstations;
440 }
441
442 static int py_samu_set_workstations(PyObject *obj, PyObject *value, void *closure)
443 {
444         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
445
446         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
447         if (!pdb_set_workstations(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
448                 return -1;
449         }
450         return 0;
451 }
452
453 static PyObject *py_samu_get_comment(PyObject *obj, void *closure)
454 {
455         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
456         PyObject *py_comment;
457         const char *comment;
458
459         comment = pdb_get_comment(sam_acct);
460         if (comment == NULL) {
461                 Py_RETURN_NONE;
462         }
463
464         py_comment = PyString_FromString(comment);
465         return py_comment;
466 }
467
468 static int py_samu_set_comment(PyObject *obj, PyObject *value, void *closure)
469 {
470         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
471
472         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
473         if (!pdb_set_comment(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
474                 return -1;
475         }
476         return 0;
477 }
478
479 static PyObject *py_samu_get_munged_dial(PyObject *obj, void *closure)
480 {
481         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
482         PyObject *py_munged_dial;
483         const char *munged_dial;
484
485         munged_dial = pdb_get_munged_dial(sam_acct);
486         if (munged_dial == NULL) {
487                 Py_RETURN_NONE;
488         }
489
490         py_munged_dial = PyString_FromString(munged_dial);
491         return py_munged_dial;
492 }
493
494 static int py_samu_set_munged_dial(PyObject *obj, PyObject *value, void *closure)
495 {
496         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
497
498         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
499         if (!pdb_set_munged_dial(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
500                 return -1;
501         }
502         return 0;
503 }
504
505 static PyObject *py_samu_get_user_sid(PyObject *obj, void *closure)
506 {
507         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
508         PyObject *py_user_sid;
509         const struct dom_sid *user_sid;
510         struct dom_sid *copy_user_sid;
511         TALLOC_CTX *mem_ctx;
512
513         user_sid = pdb_get_user_sid(sam_acct);
514         if(user_sid == NULL) {
515                 Py_RETURN_NONE;
516         }
517
518         mem_ctx = talloc_new(NULL);
519         if (mem_ctx == NULL) {
520                 PyErr_NoMemory();
521                 return NULL;
522         }
523         copy_user_sid = dom_sid_dup(mem_ctx, user_sid);
524         if (copy_user_sid == NULL) {
525                 PyErr_NoMemory();
526                 talloc_free(mem_ctx);
527                 return NULL;
528         }
529
530         py_user_sid = pytalloc_steal(dom_sid_Type, copy_user_sid);
531
532         talloc_free(mem_ctx);
533
534         return py_user_sid;
535 }
536
537 static int py_samu_set_user_sid(PyObject *obj, PyObject *value, void *closure)
538 {
539         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
540
541         PY_CHECK_TYPE(dom_sid_Type, value, return -1;);
542         if (!pdb_set_user_sid(sam_acct, (struct dom_sid *)pytalloc_get_ptr(value), PDB_CHANGED)) {
543                 return -1;
544         }
545         return 0;
546 }
547
548 static PyObject *py_samu_get_group_sid(PyObject *obj, void *closure)
549 {
550         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
551         PyObject *py_group_sid;
552         const struct dom_sid *group_sid;
553         struct dom_sid *copy_group_sid;
554         TALLOC_CTX *mem_ctx;
555
556         group_sid = pdb_get_group_sid(sam_acct);
557         if (group_sid == NULL) {
558                 Py_RETURN_NONE;
559         }
560
561         mem_ctx = talloc_new(NULL);
562         if (mem_ctx == NULL) {
563                 PyErr_NoMemory();
564                 return NULL;
565         }
566         copy_group_sid = dom_sid_dup(mem_ctx, group_sid);
567         if (copy_group_sid == NULL) {
568                 PyErr_NoMemory();
569                 talloc_free(mem_ctx);
570                 return NULL;
571         }
572
573         py_group_sid = pytalloc_steal(dom_sid_Type, copy_group_sid);
574
575         talloc_free(mem_ctx);
576
577         return py_group_sid;
578 }
579
580 static int py_samu_set_group_sid(PyObject *obj, PyObject *value, void *closure)
581 {
582         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
583
584         PY_CHECK_TYPE(dom_sid_Type, value, return -1;);
585         if (!pdb_set_group_sid(sam_acct, (struct dom_sid *)pytalloc_get_ptr(value), PDB_CHANGED)) {
586                 return -1;
587         }
588         return 0;
589 }
590
591 static PyObject *py_samu_get_lanman_passwd(PyObject *obj, void *closure)
592 {
593         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
594         PyObject *py_lm_pw;
595         const char *lm_pw;
596
597         lm_pw = (const char *)pdb_get_lanman_passwd(sam_acct);
598         if (lm_pw == NULL) {
599                 Py_RETURN_NONE;
600         }
601
602         py_lm_pw = PyString_FromString(lm_pw);
603         return py_lm_pw;
604 }
605
606 static int py_samu_set_lanman_passwd(PyObject *obj, PyObject *value, void *closure)
607 {
608         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
609
610         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
611         if (!pdb_set_lanman_passwd(sam_acct, (uint8_t *)PyString_AsString(value), PDB_CHANGED)) {
612                 return -1;
613         }
614         return 0;
615 }
616
617 static PyObject *py_samu_get_nt_passwd(PyObject *obj, void *closure)
618 {
619         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
620         PyObject *py_nt_pw;
621         const char *nt_pw;
622
623         nt_pw = (const char *)pdb_get_nt_passwd(sam_acct);
624         if (nt_pw == NULL) {
625                 Py_RETURN_NONE;
626         }
627
628         py_nt_pw = PyString_FromString(nt_pw);
629         return py_nt_pw;
630 }
631
632 static int py_samu_set_nt_passwd(PyObject *obj, PyObject *value, void *closure)
633 {
634         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
635
636         if (!pdb_set_nt_passwd(sam_acct, (uint8_t *)PyString_AsString(value), PDB_CHANGED)) {
637                 return -1;
638         }
639         return 0;
640 }
641
642 static PyObject *py_samu_get_pw_history(PyObject *obj, void *closure)
643 {
644         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
645         PyObject *py_nt_pw_his;
646         const char *nt_pw_his;
647         uint32_t hist_len;
648
649         nt_pw_his = (const char *)pdb_get_pw_history(sam_acct, &hist_len);
650         if (nt_pw_his == NULL) {
651                 Py_RETURN_NONE;
652         }
653
654         py_nt_pw_his = PyString_FromStringAndSize(nt_pw_his, hist_len);
655         return py_nt_pw_his;
656 }
657
658 static int py_samu_set_pw_history(PyObject *obj, PyObject *value, void *closure)
659 {
660         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
661         char *nt_pw_his;
662         Py_ssize_t len;
663         uint32_t hist_len;
664
665         PyString_AsStringAndSize(value, &nt_pw_his, &len);
666         hist_len = len;
667         if (!pdb_set_pw_history(sam_acct, (uint8_t *)nt_pw_his, hist_len, PDB_CHANGED)) {
668                 return -1;
669         }
670         return 0;
671 }
672
673 static PyObject *py_samu_get_plaintext_passwd(PyObject *obj, void *closure)
674 {
675         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
676         PyObject *py_plaintext_pw;
677         const char *plaintext_pw;
678
679         plaintext_pw = pdb_get_plaintext_passwd(sam_acct);
680         if (plaintext_pw == NULL) {
681                 Py_RETURN_NONE;
682         }
683
684         py_plaintext_pw = PyString_FromString(plaintext_pw);
685         return py_plaintext_pw;
686 }
687
688 static int py_samu_set_plaintext_passwd(PyObject *obj, PyObject *value, void *closure)
689 {
690         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
691
692         if (!pdb_set_plaintext_passwd(sam_acct, PyString_AsString(value))) {
693                 return -1;
694         }
695         return 0;
696 }
697
698 static PyObject *py_samu_get_acct_ctrl(PyObject *obj, void *closure)
699 {
700         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
701         PyObject *py_acct_ctrl;
702
703         py_acct_ctrl = PyInt_FromLong(pdb_get_acct_ctrl(sam_acct));
704         return py_acct_ctrl;
705 }
706
707 static int py_samu_set_acct_ctrl(PyObject *obj, PyObject *value, void *closure)
708 {
709         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
710
711         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
712         if (!pdb_set_acct_ctrl(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
713                 return -1;
714         }
715         return 0;
716 }
717
718 static PyObject *py_samu_get_logon_divs(PyObject *obj, void *closure)
719 {
720         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
721         PyObject *py_logon_divs;
722
723         py_logon_divs = PyInt_FromLong(pdb_get_logon_divs(sam_acct));
724         return py_logon_divs;
725 }
726
727 static int py_samu_set_logon_divs(PyObject *obj, PyObject *value, void *closure)
728 {
729         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
730
731         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
732         if (!pdb_set_logon_divs(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
733                 return -1;
734         }
735         return 0;
736 }
737
738 static PyObject *py_samu_get_hours_len(PyObject *obj, void *closure)
739 {
740         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
741         PyObject *py_hours_len;
742
743         py_hours_len = PyInt_FromLong(pdb_get_hours_len(sam_acct));
744         return py_hours_len;
745 }
746
747 static int py_samu_set_hours_len(PyObject *obj, PyObject *value, void *closure)
748 {
749         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
750
751         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
752         if (!pdb_set_hours_len(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
753                 return -1;
754         }
755         return 0;
756 }
757
758 static PyObject *py_samu_get_hours(PyObject *obj, void *closure)
759 {
760         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
761         PyObject *py_hours;
762         const char *hours;
763         int i;
764
765         hours = (const char *)pdb_get_hours(sam_acct);
766         if(! hours) {
767                 Py_RETURN_NONE;
768         }
769
770         if ((py_hours = PyList_New(MAX_HOURS_LEN)) == NULL) {
771                 PyErr_NoMemory();
772                 return NULL;
773         }
774
775         for (i=0; i<MAX_HOURS_LEN; i++) {
776                 PyList_SetItem(py_hours, i, PyInt_FromLong(hours[i]));
777         }
778         return py_hours;
779 }
780
781 static int py_samu_set_hours(PyObject *obj, PyObject *value, void *closure)
782 {
783         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
784         int i;
785         uint8_t *hours;
786         int hours_len;
787         bool status;
788
789         PY_CHECK_TYPE(&PyList_Type, value, return -1;);
790
791         hours_len = PyList_GET_SIZE(value);
792
793         hours = talloc_array(pytalloc_get_mem_ctx(obj), uint8_t, hours_len);
794         if (!hours) {
795                 PyErr_NoMemory();
796                 return -1;
797         }
798
799         for (i=0; i < hours_len; i++) {
800                 PY_CHECK_TYPE(&PyInt_Type, PyList_GET_ITEM(value,i), return -1;);
801                 hours[i] = PyInt_AsLong(PyList_GET_ITEM(value, i));
802         }
803
804         status = pdb_set_hours(sam_acct, hours, hours_len, PDB_CHANGED);
805         talloc_free(hours);
806
807         if(! status) {
808                 return -1;
809         }
810         return 0;
811 }
812
813 static PyObject *py_samu_get_bad_password_count(PyObject *obj, void *closure)
814 {
815         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
816         PyObject *py_bad_password_count;
817
818         py_bad_password_count = PyInt_FromLong(pdb_get_bad_password_count(sam_acct));
819         return py_bad_password_count;
820 }
821
822 static int py_samu_set_bad_password_count(PyObject *obj, PyObject *value, void *closure)
823 {
824         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
825
826         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
827         if (!pdb_set_bad_password_count(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
828                 return -1;
829         }
830         return 0;
831 }
832
833 static PyObject *py_samu_get_logon_count(PyObject *obj, void *closure)
834 {
835         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
836         PyObject *py_logon_count;
837
838         py_logon_count = PyInt_FromLong(pdb_get_logon_count(sam_acct));
839         return py_logon_count;
840 }
841
842 static int py_samu_set_logon_count(PyObject *obj, PyObject *value, void *closure)
843 {
844         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
845
846         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
847         if (!pdb_set_logon_count(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
848                 return -1;
849         }
850         return 0;
851 }
852
853 static PyObject *py_samu_get_country_code(PyObject *obj, void *closure)
854 {
855         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
856         PyObject *py_country_code;
857
858         py_country_code = PyInt_FromLong(pdb_get_country_code(sam_acct));
859         return py_country_code;
860 }
861
862 static int py_samu_set_country_code(PyObject *obj, PyObject *value, void *closure)
863 {
864         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
865
866         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
867         if (!pdb_set_country_code(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
868                 return -1;
869         }
870         return 0;
871 }
872
873 static PyObject *py_samu_get_code_page(PyObject *obj, void *closure)
874 {
875         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
876         PyObject *py_code_page;
877
878         py_code_page = PyInt_FromLong(pdb_get_code_page(sam_acct));
879         return py_code_page;
880 }
881
882 static int py_samu_set_code_page(PyObject *obj, PyObject *value, void *closure)
883 {
884         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
885
886         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
887         if (!pdb_set_code_page(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
888                 return -1;
889         }
890         return 0;
891 }
892
893 static PyGetSetDef py_samu_getsetters[] = {
894         { discard_const_p(char, "logon_time"), py_samu_get_logon_time, py_samu_set_logon_time },
895         { discard_const_p(char, "logoff_time"), py_samu_get_logoff_time, py_samu_set_logoff_time },
896         { discard_const_p(char, "kickoff_time"), py_samu_get_kickoff_time, py_samu_set_kickoff_time },
897         { discard_const_p(char, "bad_password_time"), py_samu_get_bad_password_time, py_samu_set_bad_password_time },
898         { discard_const_p(char, "pass_last_set_time"), py_samu_get_pass_last_set_time, py_samu_set_pass_last_set_time },
899         { discard_const_p(char, "pass_can_change_time"), py_samu_get_pass_can_change_time, py_samu_set_pass_can_change_time },
900         { discard_const_p(char, "pass_must_change_time"), py_samu_get_pass_must_change_time, py_samu_set_pass_must_change_time },
901         { discard_const_p(char, "username"), py_samu_get_username, py_samu_set_username },
902         { discard_const_p(char, "domain"), py_samu_get_domain, py_samu_set_domain },
903         { discard_const_p(char, "nt_username"), py_samu_get_nt_username, py_samu_set_nt_username },
904         { discard_const_p(char, "full_name"), py_samu_get_full_name, py_samu_set_full_name },
905         { discard_const_p(char, "home_dir"), py_samu_get_home_dir, py_samu_set_home_dir },
906         { discard_const_p(char, "dir_drive"), py_samu_get_dir_drive, py_samu_set_dir_drive },
907         { discard_const_p(char, "logon_script"), py_samu_get_logon_script, py_samu_set_logon_script },
908         { discard_const_p(char, "profile_path"), py_samu_get_profile_path, py_samu_set_profile_path },
909         { discard_const_p(char, "acct_desc"), py_samu_get_acct_desc, py_samu_set_acct_desc },
910         { discard_const_p(char, "workstations"), py_samu_get_workstations, py_samu_set_workstations },
911         { discard_const_p(char, "comment"), py_samu_get_comment, py_samu_set_comment },
912         { discard_const_p(char, "munged_dial"), py_samu_get_munged_dial, py_samu_set_munged_dial },
913         { discard_const_p(char, "user_sid"), py_samu_get_user_sid, py_samu_set_user_sid },
914         { discard_const_p(char, "group_sid"), py_samu_get_group_sid, py_samu_set_group_sid },
915         { discard_const_p(char, "lanman_passwd"), py_samu_get_lanman_passwd, py_samu_set_lanman_passwd },
916         { discard_const_p(char, "nt_passwd"), py_samu_get_nt_passwd, py_samu_set_nt_passwd },
917         { discard_const_p(char, "pw_history"), py_samu_get_pw_history, py_samu_set_pw_history },
918         { discard_const_p(char, "plaintext_passwd"), py_samu_get_plaintext_passwd, py_samu_set_plaintext_passwd },
919         { discard_const_p(char, "acct_ctrl"), py_samu_get_acct_ctrl, py_samu_set_acct_ctrl },
920         { discard_const_p(char, "logon_divs"), py_samu_get_logon_divs, py_samu_set_logon_divs },
921         { discard_const_p(char, "hours_len"), py_samu_get_hours_len, py_samu_set_hours_len },
922         { discard_const_p(char, "hours"), py_samu_get_hours, py_samu_set_hours },
923         { discard_const_p(char, "bad_password_count"), py_samu_get_bad_password_count, py_samu_set_bad_password_count },
924         { discard_const_p(char, "logon_count"), py_samu_get_logon_count, py_samu_set_logon_count },
925         { discard_const_p(char, "country_code"), py_samu_get_country_code, py_samu_set_country_code },
926         { discard_const_p(char, "code_page"), py_samu_get_code_page, py_samu_set_code_page },
927         { NULL }
928 };
929
930
931 /************************** PIDL Autogeneratd ******************************/
932
933 static PyObject *py_samu_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
934 {
935         struct samu *sam_acct;
936
937         sam_acct = samu_new(NULL);
938         if (!sam_acct) {
939                 PyErr_NoMemory();
940                 return NULL;
941         }
942
943         return pytalloc_steal(type, sam_acct);
944 }
945
946 static PyTypeObject PySamu = {
947         .tp_name = "passdb.samu",
948         .tp_basicsize = sizeof(pytalloc_Object),
949         .tp_getset = py_samu_getsetters,
950         .tp_methods = NULL,
951         .tp_new = py_samu_new,
952         .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
953         .tp_doc = "samu() -> samu object\n",
954 };
955
956
957 static PyObject *py_pdb_domain_info(pytalloc_Object *self, PyObject *args)
958 {
959         struct pdb_methods *methods;
960         struct pdb_domain_info *domain_info;
961         PyObject *py_domain_info;
962
963         methods = pytalloc_get_ptr(self);
964
965         domain_info = methods->get_domain_info(methods, pytalloc_get_mem_ctx(self));
966         if (! domain_info) {
967                 Py_RETURN_NONE;
968         }
969
970         if ((py_domain_info = PyDict_New()) == NULL) {
971                 PyErr_NoMemory();
972                 return NULL;
973         }
974
975         PyDict_SetItemString(py_domain_info, "name", PyString_FromString(domain_info->name));
976         PyDict_SetItemString(py_domain_info, "dns_domain", PyString_FromString(domain_info->name));
977         PyDict_SetItemString(py_domain_info, "dns_forest", PyString_FromString(domain_info->name));
978         /*
979         struct dom_sid sid;
980         struct GUID guid;
981         */
982
983         talloc_free(domain_info);
984
985         return py_domain_info;
986 }
987
988
989 static PyObject *py_pdb_getsampwnam(pytalloc_Object *self, PyObject *args)
990 {
991         NTSTATUS status;
992         const char *username;
993         struct pdb_methods *methods;
994         struct samu *sam_acct;
995         PyObject *py_sam_acct;
996         TALLOC_CTX *tframe;
997
998         if (!PyArg_ParseTuple(args, "s:getsampwnam", &username)) {
999                 return NULL;
1000         }
1001
1002         methods = pytalloc_get_ptr(self);
1003
1004         if ((tframe = talloc_stackframe()) == NULL) {
1005                 PyErr_NoMemory();
1006                 return NULL;
1007         }
1008
1009         py_sam_acct = py_samu_new(&PySamu, NULL, NULL);
1010         if (py_sam_acct == NULL) {
1011                 PyErr_NoMemory();
1012                 talloc_free(tframe);
1013                 return NULL;
1014         }
1015         sam_acct = (struct samu *)pytalloc_get_ptr(py_sam_acct);
1016
1017         status = methods->getsampwnam(methods, sam_acct, username);
1018         if (!NT_STATUS_IS_OK(status)) {
1019                 PyErr_Format(py_pdb_error, "Unable to get user information for '%s', (%d,%s)",
1020                                 username,
1021                                 NT_STATUS_V(status),
1022                                 get_friendly_nt_error_msg(status));
1023                 Py_DECREF(py_sam_acct);
1024                 talloc_free(tframe);
1025                 return NULL;
1026         }
1027
1028         talloc_free(tframe);
1029         return py_sam_acct;
1030 }
1031
1032 static PyObject *py_pdb_getsampwsid(pytalloc_Object *self, PyObject *args)
1033 {
1034         NTSTATUS status;
1035         struct pdb_methods *methods;
1036         struct samu *sam_acct;
1037         PyObject *py_sam_acct;
1038         TALLOC_CTX *tframe;
1039         PyObject *py_user_sid;
1040
1041         if (!PyArg_ParseTuple(args, "O:getsampwsid", &py_user_sid)) {
1042                 return NULL;
1043         }
1044
1045         methods = pytalloc_get_ptr(self);
1046
1047         if ((tframe = talloc_stackframe()) == NULL) {
1048                 PyErr_NoMemory();
1049                 return NULL;
1050         }
1051
1052         py_sam_acct = py_samu_new(&PySamu, NULL, NULL);
1053         if (py_sam_acct == NULL) {
1054                 PyErr_NoMemory();
1055                 talloc_free(tframe);
1056                 return NULL;
1057         }
1058         sam_acct = (struct samu *)pytalloc_get_ptr(py_sam_acct);
1059
1060         status = methods->getsampwsid(methods, sam_acct, pytalloc_get_ptr(py_user_sid));
1061         if (!NT_STATUS_IS_OK(status)) {
1062                 PyErr_Format(py_pdb_error, "Unable to get user information from SID, (%d,%s)",
1063                                 NT_STATUS_V(status),
1064                                 get_friendly_nt_error_msg(status));
1065                 Py_DECREF(py_sam_acct);
1066                 talloc_free(tframe);
1067                 return NULL;
1068         }
1069
1070         talloc_free(tframe);
1071         return py_sam_acct;
1072 }
1073
1074 static PyObject *py_pdb_create_user(pytalloc_Object *self, PyObject *args)
1075 {
1076         NTSTATUS status;
1077         struct pdb_methods *methods;
1078         const char *username;
1079         unsigned int acct_flags;
1080         unsigned int rid;
1081         TALLOC_CTX *tframe;
1082
1083         if (!PyArg_ParseTuple(args, "sI:create_user", &username, &acct_flags)) {
1084                 return NULL;
1085         }
1086
1087         methods = pytalloc_get_ptr(self);
1088
1089         if ((tframe = talloc_stackframe()) == NULL) {
1090                 PyErr_NoMemory();
1091                 return NULL;
1092         }
1093
1094         status = methods->create_user(methods, tframe, username, acct_flags, &rid);
1095         if (!NT_STATUS_IS_OK(status)) {
1096                 PyErr_Format(py_pdb_error, "Unable to create user (%s), (%d,%s)",
1097                                 username,
1098                                 NT_STATUS_V(status),
1099                                 get_friendly_nt_error_msg(status));
1100                 talloc_free(tframe);
1101                 return NULL;
1102         }
1103
1104         talloc_free(tframe);
1105         return PyInt_FromLong(rid);
1106 }
1107
1108 static PyObject *py_pdb_delete_user(pytalloc_Object *self, PyObject *args)
1109 {
1110         NTSTATUS status;
1111         struct pdb_methods *methods;
1112         TALLOC_CTX *tframe;
1113         struct samu *sam_acct;
1114         PyObject *py_sam_acct;
1115
1116         if (!PyArg_ParseTuple(args, "O!:delete_user", &PySamu, &py_sam_acct)) {
1117                 return NULL;
1118         }
1119
1120         methods = pytalloc_get_ptr(self);
1121
1122         if ((tframe = talloc_stackframe()) == NULL) {
1123                 PyErr_NoMemory();
1124                 return NULL;
1125         }
1126
1127         sam_acct = pytalloc_get_ptr(py_sam_acct);
1128
1129         status = methods->delete_user(methods, tframe, sam_acct);
1130         if (!NT_STATUS_IS_OK(status)) {
1131                 PyErr_Format(py_pdb_error, "Unable to delete user, (%d,%s)",
1132                                 NT_STATUS_V(status),
1133                                 get_friendly_nt_error_msg(status));
1134                 talloc_free(tframe);
1135                 return NULL;
1136         }
1137
1138         talloc_free(tframe);
1139         Py_RETURN_NONE;
1140 }
1141
1142 static PyObject *py_pdb_add_sam_account(pytalloc_Object *self, PyObject *args)
1143 {
1144         NTSTATUS status;
1145         struct pdb_methods *methods;
1146         TALLOC_CTX *tframe;
1147         struct samu *sam_acct;
1148         PyObject *py_sam_acct;
1149
1150         if (!PyArg_ParseTuple(args, "O!:add_sam_account", &PySamu, &py_sam_acct)) {
1151                 return NULL;
1152         }
1153
1154         methods = pytalloc_get_ptr(self);
1155
1156         if ((tframe = talloc_stackframe()) == NULL) {
1157                 PyErr_NoMemory();
1158                 return NULL;
1159         }
1160
1161         sam_acct = pytalloc_get_ptr(py_sam_acct);
1162
1163         status = methods->add_sam_account(methods, sam_acct);
1164         if (!NT_STATUS_IS_OK(status)) {
1165                 PyErr_Format(py_pdb_error, "Unable to add sam account, (%d,%s)",
1166                                 NT_STATUS_V(status),
1167                                 get_friendly_nt_error_msg(status));
1168                 talloc_free(tframe);
1169                 return NULL;
1170         }
1171
1172         talloc_free(tframe);
1173         Py_RETURN_NONE;
1174 }
1175
1176 static PyObject *py_pdb_update_sam_account(pytalloc_Object *self, PyObject *args)
1177 {
1178         NTSTATUS status;
1179         struct pdb_methods *methods;
1180         TALLOC_CTX *tframe;
1181         struct samu *sam_acct;
1182         PyObject *py_sam_acct;
1183
1184         if (!PyArg_ParseTuple(args, "O!:update_sam_account", &PySamu, &py_sam_acct)) {
1185                 return NULL;
1186         }
1187
1188         methods = pytalloc_get_ptr(self);
1189
1190         if ((tframe = talloc_stackframe()) == NULL) {
1191                 PyErr_NoMemory();
1192                 return NULL;
1193         }
1194
1195         sam_acct = pytalloc_get_ptr(py_sam_acct);
1196
1197         status = methods->update_sam_account(methods, sam_acct);
1198         if (!NT_STATUS_IS_OK(status)) {
1199                 PyErr_Format(py_pdb_error, "Unable to update sam account, (%d,%s)",
1200                                 NT_STATUS_V(status),
1201                                 get_friendly_nt_error_msg(status));
1202                 talloc_free(tframe);
1203                 return NULL;
1204         }
1205
1206         talloc_free(tframe);
1207         Py_RETURN_NONE;
1208 }
1209
1210 static PyObject *py_pdb_delete_sam_account(pytalloc_Object *self, PyObject *args)
1211 {
1212         NTSTATUS status;
1213         struct pdb_methods *methods;
1214         TALLOC_CTX *tframe;
1215         struct samu *sam_acct;
1216         PyObject *py_sam_acct;
1217
1218         if (!PyArg_ParseTuple(args, "O!:delete_sam_account", &PySamu, &py_sam_acct)) {
1219                 return NULL;
1220         }
1221
1222         methods = pytalloc_get_ptr(self);
1223
1224         if ((tframe = talloc_stackframe()) == NULL) {
1225                 PyErr_NoMemory();
1226                 return NULL;
1227         }
1228
1229         sam_acct = pytalloc_get_ptr(py_sam_acct);
1230
1231         status = methods->delete_sam_account(methods, sam_acct);
1232         if (!NT_STATUS_IS_OK(status)) {
1233                 PyErr_Format(py_pdb_error, "Unable to delete sam account, (%d,%s)",
1234                                 NT_STATUS_V(status),
1235                                 get_friendly_nt_error_msg(status));
1236                 talloc_free(tframe);
1237                 return NULL;
1238         }
1239
1240         talloc_free(tframe);
1241         Py_RETURN_NONE;
1242 }
1243
1244 static PyObject *py_pdb_rename_sam_account(pytalloc_Object *self, PyObject *args)
1245 {
1246         NTSTATUS status;
1247         struct pdb_methods *methods;
1248         TALLOC_CTX *tframe;
1249         struct samu *sam_acct;
1250         const char *new_username;
1251         PyObject *py_sam_acct;
1252
1253         if (!PyArg_ParseTuple(args, "O!s:rename_sam_account", &PySamu, &py_sam_acct,
1254                                         &new_username)) {
1255                 return NULL;
1256         }
1257
1258         methods = pytalloc_get_ptr(self);
1259
1260         if ((tframe = talloc_stackframe()) == NULL) {
1261                 PyErr_NoMemory();
1262                 return NULL;
1263         }
1264
1265         sam_acct = pytalloc_get_ptr(py_sam_acct);
1266
1267         status = methods->rename_sam_account(methods, sam_acct, new_username);
1268         if (!NT_STATUS_IS_OK(status)) {
1269                 PyErr_Format(py_pdb_error, "Unable to rename sam account, (%d,%s)",
1270                                 NT_STATUS_V(status),
1271                                 get_friendly_nt_error_msg(status));
1272                 talloc_free(tframe);
1273                 return NULL;
1274         }
1275
1276         talloc_free(tframe);
1277         Py_RETURN_NONE;
1278 }
1279
1280 static PyObject *py_pdb_search_users(pytalloc_Object *self, PyObject *args)
1281 {
1282         NTSTATUS status;
1283         struct pdb_methods *methods;
1284         TALLOC_CTX *tframe;
1285         unsigned int acct_flags;
1286         struct pdb_search *search;
1287         struct samr_displayentry *entry;
1288         PyObject *py_userlist, *py_dict;
1289
1290         if (!PyArg_ParseTuple(args, "I:search_users", &acct_flags)) {
1291                 return NULL;
1292         }
1293
1294         methods = pytalloc_get_ptr(self);
1295
1296         if ((tframe = talloc_stackframe()) == NULL) {
1297                 PyErr_NoMemory();
1298                 return NULL;
1299         }
1300
1301         search = talloc_zero(tframe, struct pdb_search);
1302         if (search == NULL) {
1303                 PyErr_NoMemory();
1304                 talloc_free(tframe);
1305                 return NULL;
1306         }
1307
1308         if (!methods->search_users(methods, search, acct_flags)) {
1309                 PyErr_Format(py_pdb_error, "Unable to search users, (%d,%s)",
1310                                 NT_STATUS_V(status),
1311                                 get_friendly_nt_error_msg(status));
1312                 talloc_free(tframe);
1313                 return NULL;
1314         }
1315
1316         entry = talloc_zero(tframe, struct samr_displayentry);
1317         if (entry == NULL) {
1318                 PyErr_NoMemory();
1319                 talloc_free(tframe);
1320                 return NULL;
1321         }
1322
1323         py_userlist = PyList_New(0);
1324         if (py_userlist == NULL) {
1325                 PyErr_NoMemory();
1326                 talloc_free(tframe);
1327                 return NULL;
1328         }
1329
1330         while (search->next_entry(search, entry)) {
1331                 py_dict = PyDict_New();
1332                 if (py_dict == NULL) {
1333                         PyErr_NoMemory();
1334                 } else {
1335                         PyDict_SetItemString(py_dict, "idx", PyInt_FromLong(entry->idx));
1336                         PyDict_SetItemString(py_dict, "rid", PyInt_FromLong(entry->rid));
1337                         PyDict_SetItemString(py_dict, "acct_flags", PyInt_FromLong(entry->acct_flags));
1338                         PyDict_SetItemString(py_dict, "account_name", PyString_FromString(entry->account_name));
1339                         PyDict_SetItemString(py_dict, "fullname", PyString_FromString(entry->fullname));
1340                         PyDict_SetItemString(py_dict, "description", PyString_FromString(entry->description));
1341                         PyList_Append(py_userlist, py_dict);
1342                 }
1343         }
1344         search->search_end(search);
1345
1346         talloc_free(tframe);
1347
1348         return py_userlist;
1349 }
1350
1351 static PyMethodDef py_pdb_methods[] = {
1352         { "domain_info", (PyCFunction)py_pdb_domain_info, METH_NOARGS,
1353                 "domain_info() -> str\n\n \
1354                 Get domain for the database." },
1355         { "getsampwnam", (PyCFunction)py_pdb_getsampwnam, METH_VARARGS,
1356                 "getsampwnam(username) -> samu object\n\n \
1357                 Get user information." },
1358         { "getsampwsid", (PyCFunction)py_pdb_getsampwsid, METH_VARARGS,
1359                 "getsampwsid(sid) -> samu object\n\n \
1360                 Get user information from user_sid (dcerpc.security.dom_sid object)." },
1361         { "create_user", (PyCFunction)py_pdb_create_user, METH_VARARGS,
1362                 "create_user(username, acct_flags) -> rid\n\n \
1363                 Create user. acct_flags are samr account control flags." },
1364         { "delete_user", (PyCFunction)py_pdb_delete_user, METH_VARARGS,
1365                 "delete_user(samu object) -> None\n\n \
1366                 Delete user." },
1367         { "add_sam_account", (PyCFunction)py_pdb_add_sam_account, METH_VARARGS,
1368                 "add_sam_account(samu object) -> None\n\n \
1369                 Add SAM account." },
1370         { "update_sam_account", (PyCFunction)py_pdb_update_sam_account, METH_VARARGS,
1371                 "update_sam_account(samu object) -> None\n\n \
1372                 Update SAM account." },
1373         { "delete_sam_account", (PyCFunction)py_pdb_delete_sam_account, METH_VARARGS,
1374                 "delete_sam_account(samu object) -> None\n\n \
1375                 Delete SAM account." },
1376         { "rename_sam_account", (PyCFunction)py_pdb_rename_sam_account, METH_VARARGS,
1377                 "rename_sam_account(samu object1, new_username) -> None\n\n \
1378                 Rename SAM account." },
1379         { "search_users", (PyCFunction)py_pdb_search_users, METH_VARARGS,
1380                 "search_users(acct_flags) -> List\n\n \
1381                 Search users. acct_flags are samr account control flags.\n \
1382                 Each entry in the list is a dictionary with keys - \
1383                 idx, rid, acct_flags, account_name, fullname, description." },
1384         { NULL },
1385 };
1386
1387
1388 static PyObject *py_pdb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1389 {
1390         const char *url = NULL;
1391         PyObject *pypdb;
1392         NTSTATUS status;
1393         struct pdb_methods *methods;
1394
1395         if (!PyArg_ParseTuple(args, "s", &url)) {
1396                 return NULL;
1397         }
1398
1399         /* Initalize list of methods */
1400         status = make_pdb_method_name(&methods, url);
1401         if (!NT_STATUS_IS_OK(status)) {
1402                 PyErr_Format(py_pdb_error, "Cannot load backend methods for '%s' backend (%d,%s)",
1403                                 url,
1404                                 NT_STATUS_V(status),
1405                                 get_friendly_nt_error_msg(status));
1406                 return NULL;
1407         }
1408
1409         if ((pypdb = pytalloc_steal(type, methods)) == NULL) {
1410                 PyErr_NoMemory();
1411                 return NULL;
1412         }
1413
1414         return pypdb;
1415 }
1416
1417
1418 static PyTypeObject PyPDB = {
1419         .tp_name = "passdb.PDB",
1420         .tp_basicsize = sizeof(pytalloc_Object),
1421         .tp_new = py_pdb_new,
1422         .tp_flags = Py_TPFLAGS_DEFAULT,
1423         .tp_methods = py_pdb_methods,
1424         .tp_doc = "PDB(url[, read_write_flags]) -> Password DB object\n",
1425 };
1426
1427
1428 /*
1429  * Return a list of passdb backends
1430  */
1431 static PyObject *py_passdb_backends(PyObject *self)
1432 {
1433         PyObject *py_blist;
1434         const struct pdb_init_function_entry *entry;
1435
1436         entry = pdb_get_backends();
1437         if(! entry) {
1438                 Py_RETURN_NONE;
1439         }
1440
1441         if((py_blist = PyList_New(0)) == NULL) {
1442                 PyErr_NoMemory();
1443                 return NULL;
1444         }
1445
1446         while(entry) {
1447                 PyList_Append(py_blist, PyString_FromString(entry->name));
1448                 entry = entry->next;
1449         }
1450
1451         return py_blist;
1452 }
1453
1454
1455 static PyObject *py_set_smb_config(PyObject *self, PyObject *args)
1456 {
1457         const char *smb_config;
1458
1459         if (!PyArg_ParseTuple(args, "s", &smb_config)) {
1460                 return NULL;
1461         }
1462
1463         /* Load smbconf parameters */
1464         if (!lp_load_global(smb_config)) {
1465                 PyErr_Format(py_pdb_error, "Cannot open '%s'", smb_config);
1466                 return NULL;
1467         }
1468
1469         Py_RETURN_NONE;
1470 }
1471
1472
1473 static PyObject *py_set_secrets_dir(PyObject *self, PyObject *args)
1474 {
1475         const char *private_dir;
1476
1477         if (!PyArg_ParseTuple(args, "s", &private_dir)) {
1478                 return NULL;
1479         }
1480
1481         /* Initialize secrets database */
1482         if (!secrets_init_path(private_dir)) {
1483                 PyErr_Format(py_pdb_error, "Cannot open secrets file database in '%s'",
1484                                 private_dir);
1485                 return NULL;
1486         }
1487
1488         Py_RETURN_NONE;
1489 }
1490
1491
1492 static PyMethodDef py_passdb_methods[] = {
1493         { "get_backends", (PyCFunction)py_passdb_backends, METH_NOARGS,
1494                 "get_backends() -> list\n\n \
1495                 Get a list of password database backends supported." },
1496         { "set_smb_config", (PyCFunction)py_set_smb_config, METH_VARARGS,
1497                 "set_smb_config(path) -> None\n\n \
1498                 Set path to smb.conf file to load configuration parameters." },
1499         { "set_secrets_dir", (PyCFunction)py_set_secrets_dir, METH_VARARGS,
1500                 "set_secrets_dir(private_dir) -> None\n\n \
1501                 Set path to private directory to load secrets database from non-default location." },
1502         { NULL },
1503 };
1504
1505 void initpassdb(void)
1506 {
1507         PyObject *m, *mod;
1508         char exception_name[] = "passdb.error";
1509
1510         PyTypeObject *talloc_type = pytalloc_GetObjectType();
1511         if (talloc_type == NULL) {
1512                 return;
1513         }
1514
1515         PyPDB.tp_base = talloc_type;
1516         if (PyType_Ready(&PyPDB) < 0) {
1517                 return;
1518         }
1519
1520         PySamu.tp_base = talloc_type;
1521         if (PyType_Ready(&PySamu) < 0) {
1522                 return;
1523         }
1524
1525         m = Py_InitModule3("passdb", py_passdb_methods, "SAMBA Password Database");
1526         if (m == NULL) {
1527             return;
1528         }
1529
1530         /* Create new exception for passdb module */
1531         py_pdb_error = PyErr_NewException(exception_name, NULL, NULL);
1532         Py_INCREF(py_pdb_error);
1533         PyModule_AddObject(m, "error", py_pdb_error);
1534
1535         Py_INCREF(&PyPDB);
1536         PyModule_AddObject(m, "PDB", (PyObject *)&PyPDB);
1537
1538         /* Import dom_sid type from dcerpc.security */
1539         mod = PyImport_ImportModule("samba.dcerpc.security");
1540         if (mod == NULL) {
1541                 return;
1542         }
1543
1544         dom_sid_Type = (PyTypeObject *)PyObject_GetAttrString(mod, "dom_sid");
1545         Py_DECREF(mod);
1546         if (dom_sid_Type == NULL) {
1547                 return;
1548         }
1549
1550         /* FIXME: Load passdb backends
1551          *        Currently there is no equivalent public function for lazy_initialize_passdb()
1552          */
1553 }