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