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