passdb: Allocate talloc stackframe before calling in pdb functions.
[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         TALLOC_CTX *tframe;
963
964         methods = pytalloc_get_ptr(self);
965
966         if ((tframe = talloc_stackframe()) == NULL) {
967                 PyErr_NoMemory();
968                 return NULL;
969         }
970
971         domain_info = methods->get_domain_info(methods, tframe);
972         if (! domain_info) {
973                 Py_RETURN_NONE;
974         }
975
976         if ((py_domain_info = PyDict_New()) == NULL) {
977                 PyErr_NoMemory();
978                 return NULL;
979         }
980
981         PyDict_SetItemString(py_domain_info, "name", PyString_FromString(domain_info->name));
982         PyDict_SetItemString(py_domain_info, "dns_domain", PyString_FromString(domain_info->name));
983         PyDict_SetItemString(py_domain_info, "dns_forest", PyString_FromString(domain_info->name));
984         /*
985         struct dom_sid sid;
986         struct GUID guid;
987         */
988
989         talloc_free(tframe);
990
991         return py_domain_info;
992 }
993
994
995 static PyObject *py_pdb_getsampwnam(pytalloc_Object *self, PyObject *args)
996 {
997         NTSTATUS status;
998         const char *username;
999         struct pdb_methods *methods;
1000         struct samu *sam_acct;
1001         PyObject *py_sam_acct;
1002         TALLOC_CTX *tframe;
1003
1004         if (!PyArg_ParseTuple(args, "s:getsampwnam", &username)) {
1005                 return NULL;
1006         }
1007
1008         methods = pytalloc_get_ptr(self);
1009
1010         if ((tframe = talloc_stackframe()) == NULL) {
1011                 PyErr_NoMemory();
1012                 return NULL;
1013         }
1014
1015         py_sam_acct = py_samu_new(&PySamu, NULL, NULL);
1016         if (py_sam_acct == NULL) {
1017                 PyErr_NoMemory();
1018                 talloc_free(tframe);
1019                 return NULL;
1020         }
1021         sam_acct = (struct samu *)pytalloc_get_ptr(py_sam_acct);
1022
1023         status = methods->getsampwnam(methods, sam_acct, username);
1024         if (!NT_STATUS_IS_OK(status)) {
1025                 PyErr_Format(py_pdb_error, "Unable to get user information for '%s', (%d,%s)",
1026                                 username,
1027                                 NT_STATUS_V(status),
1028                                 get_friendly_nt_error_msg(status));
1029                 Py_DECREF(py_sam_acct);
1030                 talloc_free(tframe);
1031                 return NULL;
1032         }
1033
1034         talloc_free(tframe);
1035         return py_sam_acct;
1036 }
1037
1038 static PyObject *py_pdb_getsampwsid(pytalloc_Object *self, PyObject *args)
1039 {
1040         NTSTATUS status;
1041         struct pdb_methods *methods;
1042         struct samu *sam_acct;
1043         PyObject *py_sam_acct;
1044         TALLOC_CTX *tframe;
1045         PyObject *py_user_sid;
1046
1047         if (!PyArg_ParseTuple(args, "O:getsampwsid", &py_user_sid)) {
1048                 return NULL;
1049         }
1050
1051         methods = pytalloc_get_ptr(self);
1052
1053         if ((tframe = talloc_stackframe()) == NULL) {
1054                 PyErr_NoMemory();
1055                 return NULL;
1056         }
1057
1058         py_sam_acct = py_samu_new(&PySamu, NULL, NULL);
1059         if (py_sam_acct == NULL) {
1060                 PyErr_NoMemory();
1061                 talloc_free(tframe);
1062                 return NULL;
1063         }
1064         sam_acct = (struct samu *)pytalloc_get_ptr(py_sam_acct);
1065
1066         status = methods->getsampwsid(methods, sam_acct, pytalloc_get_ptr(py_user_sid));
1067         if (!NT_STATUS_IS_OK(status)) {
1068                 PyErr_Format(py_pdb_error, "Unable to get user information from SID, (%d,%s)",
1069                                 NT_STATUS_V(status),
1070                                 get_friendly_nt_error_msg(status));
1071                 Py_DECREF(py_sam_acct);
1072                 talloc_free(tframe);
1073                 return NULL;
1074         }
1075
1076         talloc_free(tframe);
1077         return py_sam_acct;
1078 }
1079
1080 static PyObject *py_pdb_create_user(pytalloc_Object *self, PyObject *args)
1081 {
1082         NTSTATUS status;
1083         struct pdb_methods *methods;
1084         const char *username;
1085         unsigned int acct_flags;
1086         unsigned int rid;
1087         TALLOC_CTX *tframe;
1088
1089         if (!PyArg_ParseTuple(args, "sI:create_user", &username, &acct_flags)) {
1090                 return NULL;
1091         }
1092
1093         methods = pytalloc_get_ptr(self);
1094
1095         if ((tframe = talloc_stackframe()) == NULL) {
1096                 PyErr_NoMemory();
1097                 return NULL;
1098         }
1099
1100         status = methods->create_user(methods, tframe, username, acct_flags, &rid);
1101         if (!NT_STATUS_IS_OK(status)) {
1102                 PyErr_Format(py_pdb_error, "Unable to create user (%s), (%d,%s)",
1103                                 username,
1104                                 NT_STATUS_V(status),
1105                                 get_friendly_nt_error_msg(status));
1106                 talloc_free(tframe);
1107                 return NULL;
1108         }
1109
1110         talloc_free(tframe);
1111         return PyInt_FromLong(rid);
1112 }
1113
1114 static PyObject *py_pdb_delete_user(pytalloc_Object *self, PyObject *args)
1115 {
1116         NTSTATUS status;
1117         struct pdb_methods *methods;
1118         TALLOC_CTX *tframe;
1119         struct samu *sam_acct;
1120         PyObject *py_sam_acct;
1121
1122         if (!PyArg_ParseTuple(args, "O!:delete_user", &PySamu, &py_sam_acct)) {
1123                 return NULL;
1124         }
1125
1126         methods = pytalloc_get_ptr(self);
1127
1128         if ((tframe = talloc_stackframe()) == NULL) {
1129                 PyErr_NoMemory();
1130                 return NULL;
1131         }
1132
1133         sam_acct = pytalloc_get_ptr(py_sam_acct);
1134
1135         status = methods->delete_user(methods, tframe, sam_acct);
1136         if (!NT_STATUS_IS_OK(status)) {
1137                 PyErr_Format(py_pdb_error, "Unable to delete user, (%d,%s)",
1138                                 NT_STATUS_V(status),
1139                                 get_friendly_nt_error_msg(status));
1140                 talloc_free(tframe);
1141                 return NULL;
1142         }
1143
1144         talloc_free(tframe);
1145         Py_RETURN_NONE;
1146 }
1147
1148 static PyObject *py_pdb_add_sam_account(pytalloc_Object *self, PyObject *args)
1149 {
1150         NTSTATUS status;
1151         struct pdb_methods *methods;
1152         TALLOC_CTX *tframe;
1153         struct samu *sam_acct;
1154         PyObject *py_sam_acct;
1155
1156         if (!PyArg_ParseTuple(args, "O!:add_sam_account", &PySamu, &py_sam_acct)) {
1157                 return NULL;
1158         }
1159
1160         methods = pytalloc_get_ptr(self);
1161
1162         if ((tframe = talloc_stackframe()) == NULL) {
1163                 PyErr_NoMemory();
1164                 return NULL;
1165         }
1166
1167         sam_acct = pytalloc_get_ptr(py_sam_acct);
1168
1169         status = methods->add_sam_account(methods, sam_acct);
1170         if (!NT_STATUS_IS_OK(status)) {
1171                 PyErr_Format(py_pdb_error, "Unable to add sam account, (%d,%s)",
1172                                 NT_STATUS_V(status),
1173                                 get_friendly_nt_error_msg(status));
1174                 talloc_free(tframe);
1175                 return NULL;
1176         }
1177
1178         talloc_free(tframe);
1179         Py_RETURN_NONE;
1180 }
1181
1182 static PyObject *py_pdb_update_sam_account(pytalloc_Object *self, PyObject *args)
1183 {
1184         NTSTATUS status;
1185         struct pdb_methods *methods;
1186         TALLOC_CTX *tframe;
1187         struct samu *sam_acct;
1188         PyObject *py_sam_acct;
1189
1190         if (!PyArg_ParseTuple(args, "O!:update_sam_account", &PySamu, &py_sam_acct)) {
1191                 return NULL;
1192         }
1193
1194         methods = pytalloc_get_ptr(self);
1195
1196         if ((tframe = talloc_stackframe()) == NULL) {
1197                 PyErr_NoMemory();
1198                 return NULL;
1199         }
1200
1201         sam_acct = pytalloc_get_ptr(py_sam_acct);
1202
1203         status = methods->update_sam_account(methods, sam_acct);
1204         if (!NT_STATUS_IS_OK(status)) {
1205                 PyErr_Format(py_pdb_error, "Unable to update sam account, (%d,%s)",
1206                                 NT_STATUS_V(status),
1207                                 get_friendly_nt_error_msg(status));
1208                 talloc_free(tframe);
1209                 return NULL;
1210         }
1211
1212         talloc_free(tframe);
1213         Py_RETURN_NONE;
1214 }
1215
1216 static PyObject *py_pdb_delete_sam_account(pytalloc_Object *self, PyObject *args)
1217 {
1218         NTSTATUS status;
1219         struct pdb_methods *methods;
1220         TALLOC_CTX *tframe;
1221         struct samu *sam_acct;
1222         PyObject *py_sam_acct;
1223
1224         if (!PyArg_ParseTuple(args, "O!:delete_sam_account", &PySamu, &py_sam_acct)) {
1225                 return NULL;
1226         }
1227
1228         methods = pytalloc_get_ptr(self);
1229
1230         if ((tframe = talloc_stackframe()) == NULL) {
1231                 PyErr_NoMemory();
1232                 return NULL;
1233         }
1234
1235         sam_acct = pytalloc_get_ptr(py_sam_acct);
1236
1237         status = methods->delete_sam_account(methods, sam_acct);
1238         if (!NT_STATUS_IS_OK(status)) {
1239                 PyErr_Format(py_pdb_error, "Unable to delete sam account, (%d,%s)",
1240                                 NT_STATUS_V(status),
1241                                 get_friendly_nt_error_msg(status));
1242                 talloc_free(tframe);
1243                 return NULL;
1244         }
1245
1246         talloc_free(tframe);
1247         Py_RETURN_NONE;
1248 }
1249
1250 static PyObject *py_pdb_rename_sam_account(pytalloc_Object *self, PyObject *args)
1251 {
1252         NTSTATUS status;
1253         struct pdb_methods *methods;
1254         TALLOC_CTX *tframe;
1255         struct samu *sam_acct;
1256         const char *new_username;
1257         PyObject *py_sam_acct;
1258
1259         if (!PyArg_ParseTuple(args, "O!s:rename_sam_account", &PySamu, &py_sam_acct,
1260                                         &new_username)) {
1261                 return NULL;
1262         }
1263
1264         methods = pytalloc_get_ptr(self);
1265
1266         if ((tframe = talloc_stackframe()) == NULL) {
1267                 PyErr_NoMemory();
1268                 return NULL;
1269         }
1270
1271         sam_acct = pytalloc_get_ptr(py_sam_acct);
1272
1273         status = methods->rename_sam_account(methods, sam_acct, new_username);
1274         if (!NT_STATUS_IS_OK(status)) {
1275                 PyErr_Format(py_pdb_error, "Unable to rename sam account, (%d,%s)",
1276                                 NT_STATUS_V(status),
1277                                 get_friendly_nt_error_msg(status));
1278                 talloc_free(tframe);
1279                 return NULL;
1280         }
1281
1282         talloc_free(tframe);
1283         Py_RETURN_NONE;
1284 }
1285
1286 static PyObject *py_pdb_search_users(pytalloc_Object *self, PyObject *args)
1287 {
1288         NTSTATUS status;
1289         struct pdb_methods *methods;
1290         TALLOC_CTX *tframe;
1291         unsigned int acct_flags;
1292         struct pdb_search *search;
1293         struct samr_displayentry *entry;
1294         PyObject *py_userlist, *py_dict;
1295
1296         if (!PyArg_ParseTuple(args, "I:search_users", &acct_flags)) {
1297                 return NULL;
1298         }
1299
1300         methods = pytalloc_get_ptr(self);
1301
1302         if ((tframe = talloc_stackframe()) == NULL) {
1303                 PyErr_NoMemory();
1304                 return NULL;
1305         }
1306
1307         search = talloc_zero(tframe, struct pdb_search);
1308         if (search == NULL) {
1309                 PyErr_NoMemory();
1310                 talloc_free(tframe);
1311                 return NULL;
1312         }
1313
1314         if (!methods->search_users(methods, search, acct_flags)) {
1315                 PyErr_Format(py_pdb_error, "Unable to search users, (%d,%s)",
1316                                 NT_STATUS_V(status),
1317                                 get_friendly_nt_error_msg(status));
1318                 talloc_free(tframe);
1319                 return NULL;
1320         }
1321
1322         entry = talloc_zero(tframe, struct samr_displayentry);
1323         if (entry == NULL) {
1324                 PyErr_NoMemory();
1325                 talloc_free(tframe);
1326                 return NULL;
1327         }
1328
1329         py_userlist = PyList_New(0);
1330         if (py_userlist == NULL) {
1331                 PyErr_NoMemory();
1332                 talloc_free(tframe);
1333                 return NULL;
1334         }
1335
1336         while (search->next_entry(search, entry)) {
1337                 py_dict = PyDict_New();
1338                 if (py_dict == NULL) {
1339                         PyErr_NoMemory();
1340                 } else {
1341                         PyDict_SetItemString(py_dict, "idx", PyInt_FromLong(entry->idx));
1342                         PyDict_SetItemString(py_dict, "rid", PyInt_FromLong(entry->rid));
1343                         PyDict_SetItemString(py_dict, "acct_flags", PyInt_FromLong(entry->acct_flags));
1344                         PyDict_SetItemString(py_dict, "account_name", PyString_FromString(entry->account_name));
1345                         PyDict_SetItemString(py_dict, "fullname", PyString_FromString(entry->fullname));
1346                         PyDict_SetItemString(py_dict, "description", PyString_FromString(entry->description));
1347                         PyList_Append(py_userlist, py_dict);
1348                 }
1349         }
1350         search->search_end(search);
1351
1352         talloc_free(tframe);
1353
1354         return py_userlist;
1355 }
1356
1357 static PyMethodDef py_pdb_methods[] = {
1358         { "domain_info", (PyCFunction)py_pdb_domain_info, METH_NOARGS,
1359                 "domain_info() -> str\n\n \
1360                 Get domain for the database." },
1361         { "getsampwnam", (PyCFunction)py_pdb_getsampwnam, METH_VARARGS,
1362                 "getsampwnam(username) -> samu object\n\n \
1363                 Get user information." },
1364         { "getsampwsid", (PyCFunction)py_pdb_getsampwsid, METH_VARARGS,
1365                 "getsampwsid(sid) -> samu object\n\n \
1366                 Get user information from user_sid (dcerpc.security.dom_sid object)." },
1367         { "create_user", (PyCFunction)py_pdb_create_user, METH_VARARGS,
1368                 "create_user(username, acct_flags) -> rid\n\n \
1369                 Create user. acct_flags are samr account control flags." },
1370         { "delete_user", (PyCFunction)py_pdb_delete_user, METH_VARARGS,
1371                 "delete_user(samu object) -> None\n\n \
1372                 Delete user." },
1373         { "add_sam_account", (PyCFunction)py_pdb_add_sam_account, METH_VARARGS,
1374                 "add_sam_account(samu object) -> None\n\n \
1375                 Add SAM account." },
1376         { "update_sam_account", (PyCFunction)py_pdb_update_sam_account, METH_VARARGS,
1377                 "update_sam_account(samu object) -> None\n\n \
1378                 Update SAM account." },
1379         { "delete_sam_account", (PyCFunction)py_pdb_delete_sam_account, METH_VARARGS,
1380                 "delete_sam_account(samu object) -> None\n\n \
1381                 Delete SAM account." },
1382         { "rename_sam_account", (PyCFunction)py_pdb_rename_sam_account, METH_VARARGS,
1383                 "rename_sam_account(samu object1, new_username) -> None\n\n \
1384                 Rename SAM account." },
1385         { "search_users", (PyCFunction)py_pdb_search_users, METH_VARARGS,
1386                 "search_users(acct_flags) -> List\n\n \
1387                 Search users. acct_flags are samr account control flags.\n \
1388                 Each entry in the list is a dictionary with keys - \
1389                 idx, rid, acct_flags, account_name, fullname, description." },
1390         { NULL },
1391 };
1392
1393
1394 static PyObject *py_pdb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1395 {
1396         const char *url = NULL;
1397         PyObject *pypdb;
1398         NTSTATUS status;
1399         struct pdb_methods *methods;
1400
1401         if (!PyArg_ParseTuple(args, "s", &url)) {
1402                 return NULL;
1403         }
1404
1405         /* Initalize list of methods */
1406         status = make_pdb_method_name(&methods, url);
1407         if (!NT_STATUS_IS_OK(status)) {
1408                 PyErr_Format(py_pdb_error, "Cannot load backend methods for '%s' backend (%d,%s)",
1409                                 url,
1410                                 NT_STATUS_V(status),
1411                                 get_friendly_nt_error_msg(status));
1412                 return NULL;
1413         }
1414
1415         if ((pypdb = pytalloc_steal(type, methods)) == NULL) {
1416                 PyErr_NoMemory();
1417                 return NULL;
1418         }
1419
1420         return pypdb;
1421 }
1422
1423
1424 static PyTypeObject PyPDB = {
1425         .tp_name = "passdb.PDB",
1426         .tp_basicsize = sizeof(pytalloc_Object),
1427         .tp_new = py_pdb_new,
1428         .tp_flags = Py_TPFLAGS_DEFAULT,
1429         .tp_methods = py_pdb_methods,
1430         .tp_doc = "PDB(url[, read_write_flags]) -> Password DB object\n",
1431 };
1432
1433
1434 /*
1435  * Return a list of passdb backends
1436  */
1437 static PyObject *py_passdb_backends(PyObject *self)
1438 {
1439         PyObject *py_blist;
1440         const struct pdb_init_function_entry *entry;
1441         TALLOC_CTX *tframe;
1442
1443         if ((tframe = talloc_stackframe()) == NULL) {
1444                 PyErr_NoMemory();
1445                 return NULL;
1446         }
1447
1448         entry = pdb_get_backends();
1449         if(! entry) {
1450                 Py_RETURN_NONE;
1451         }
1452
1453         if((py_blist = PyList_New(0)) == NULL) {
1454                 PyErr_NoMemory();
1455                 return NULL;
1456         }
1457
1458         while(entry) {
1459                 PyList_Append(py_blist, PyString_FromString(entry->name));
1460                 entry = entry->next;
1461         }
1462
1463         talloc_free(tframe);
1464
1465         return py_blist;
1466 }
1467
1468
1469 static PyObject *py_set_smb_config(PyObject *self, PyObject *args)
1470 {
1471         const char *smb_config;
1472         TALLOC_CTX *tframe;
1473
1474         if (!PyArg_ParseTuple(args, "s", &smb_config)) {
1475                 return NULL;
1476         }
1477
1478         if ((tframe = talloc_stackframe()) == NULL) {
1479                 PyErr_NoMemory();
1480                 return NULL;
1481         }
1482
1483         /* Load smbconf parameters */
1484         if (!lp_load_global(smb_config)) {
1485                 PyErr_Format(py_pdb_error, "Cannot open '%s'", smb_config);
1486                 return NULL;
1487         }
1488
1489         talloc_free(tframe);
1490
1491         Py_RETURN_NONE;
1492 }
1493
1494
1495 static PyObject *py_set_secrets_dir(PyObject *self, PyObject *args)
1496 {
1497         const char *private_dir;
1498         TALLOC_CTX *tframe;
1499
1500         if (!PyArg_ParseTuple(args, "s", &private_dir)) {
1501                 return NULL;
1502         }
1503
1504         if ((tframe = talloc_stackframe()) == NULL) {
1505                 PyErr_NoMemory();
1506                 return NULL;
1507         }
1508
1509         /* Initialize secrets database */
1510         if (!secrets_init_path(private_dir)) {
1511                 PyErr_Format(py_pdb_error, "Cannot open secrets file database in '%s'",
1512                                 private_dir);
1513                 return NULL;
1514         }
1515
1516         talloc_free(tframe);
1517
1518         Py_RETURN_NONE;
1519 }
1520
1521
1522 static PyMethodDef py_passdb_methods[] = {
1523         { "get_backends", (PyCFunction)py_passdb_backends, METH_NOARGS,
1524                 "get_backends() -> list\n\n \
1525                 Get a list of password database backends supported." },
1526         { "set_smb_config", (PyCFunction)py_set_smb_config, METH_VARARGS,
1527                 "set_smb_config(path) -> None\n\n \
1528                 Set path to smb.conf file to load configuration parameters." },
1529         { "set_secrets_dir", (PyCFunction)py_set_secrets_dir, METH_VARARGS,
1530                 "set_secrets_dir(private_dir) -> None\n\n \
1531                 Set path to private directory to load secrets database from non-default location." },
1532         { NULL },
1533 };
1534
1535 void initpassdb(void)
1536 {
1537         PyObject *m, *mod;
1538         char exception_name[] = "passdb.error";
1539
1540         PyTypeObject *talloc_type = pytalloc_GetObjectType();
1541         if (talloc_type == NULL) {
1542                 return;
1543         }
1544
1545         PyPDB.tp_base = talloc_type;
1546         if (PyType_Ready(&PyPDB) < 0) {
1547                 return;
1548         }
1549
1550         PySamu.tp_base = talloc_type;
1551         if (PyType_Ready(&PySamu) < 0) {
1552                 return;
1553         }
1554
1555         m = Py_InitModule3("passdb", py_passdb_methods, "SAMBA Password Database");
1556         if (m == NULL) {
1557             return;
1558         }
1559
1560         /* Create new exception for passdb module */
1561         py_pdb_error = PyErr_NewException(exception_name, NULL, NULL);
1562         Py_INCREF(py_pdb_error);
1563         PyModule_AddObject(m, "error", py_pdb_error);
1564
1565         Py_INCREF(&PyPDB);
1566         PyModule_AddObject(m, "PDB", (PyObject *)&PyPDB);
1567
1568         /* Import dom_sid type from dcerpc.security */
1569         mod = PyImport_ImportModule("samba.dcerpc.security");
1570         if (mod == NULL) {
1571                 return;
1572         }
1573
1574         dom_sid_Type = (PyTypeObject *)PyObject_GetAttrString(mod, "dom_sid");
1575         Py_DECREF(mod);
1576         if (dom_sid_Type == NULL) {
1577                 return;
1578         }
1579
1580         /* FIXME: Load passdb backends
1581          *        Currently there is no equivalent public function for lazy_initialize_passdb()
1582          */
1583 }