import HEAD into svn+ssh://svn.samba.org/home/svn/samba/trunk
[metze/old/v3-2-winbind-ndr.git] / source / sam / gums_api.c
1 /* 
2    Unix SMB/CIFS implementation.
3    GUMS structures
4    Copyright (C) Simo Sorce 2002
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 2 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, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 /* Functions to get/set info from a GUMS object */
24
25 NTSTATUS gums_create_object(GUMS_OBJECT **obj, uint32 type)
26 {
27         TALLOC_CTX *mem_ctx;
28         GUMS_OBJECT *go;
29         NTSTATUS ret;
30
31         mem_ctx = talloc_init("gums_create_object");
32         if (!mem_ctx) {
33                 DEBUG(0, ("gums_create_object: Out of memory!\n"));
34                 *obj = NULL;
35                 return NT_STATUS_NO_MEMORY;
36         }
37
38         go = talloc_zero(mem_ctx, sizeof(GUMS_OBJECT));
39         if (!go) {
40                 DEBUG(0, ("gums_create_object: Out of memory!\n"));
41                 talloc_destroy(mem_ctx);
42                 *obj = NULL;
43                 return NT_STATUS_NO_MEMORY;
44         }
45
46         go->mem_ctx = mem_ctx;
47         go->type = type;
48         go->version = GUMS_OBJECT_VERSION;
49
50         switch(type) {
51                 case GUMS_OBJ_DOMAIN:
52                         go->domain = (GUMS_DOMAIN *)talloc_zero(mem_ctx, sizeof(GUMS_DOMAIN));
53                         if (!(go->domain)) {
54                                 ret = NT_STATUS_NO_MEMORY;
55                                 DEBUG(0, ("gums_create_object: Out of memory!\n"));
56                                 goto error;
57                         }
58
59                         break;
60
61 /*
62                 case GUMS_OBJ_WORKSTATION_TRUST:
63                 case GUMS_OBJ_SERVER_TRUST:
64                 case GUMS_OBJ_DOMAIN_TRUST:
65 */
66                 case GUMS_OBJ_NORMAL_USER:
67                         go->user = (GUMS_USER *)talloc_zero(mem_ctx, sizeof(GUMS_USER));
68                         if (!(go->user)) {
69                                 ret = NT_STATUS_NO_MEMORY;
70                                 DEBUG(0, ("gums_create_object: Out of memory!\n"));
71                                 goto error;
72                         }
73                         gums_set_user_acct_ctrl(go, ACB_NORMAL);
74                         gums_set_user_hours(go, 0, NULL);
75
76                         break;
77
78                 case GUMS_OBJ_GROUP:
79                 case GUMS_OBJ_ALIAS:
80                         go->group = (GUMS_GROUP *)talloc_zero(mem_ctx, sizeof(GUMS_GROUP));
81                         if (!(go->group)) {
82                                 ret = NT_STATUS_NO_MEMORY;
83                                 DEBUG(0, ("gums_create_object: Out of memory!\n"));
84                                 goto error;
85                         }
86
87                         break;
88
89                 default:
90                         /* TODO: throw error */
91                         ret = NT_STATUS_OBJECT_TYPE_MISMATCH;
92                         goto error;
93         }
94
95         *obj = go;
96         return NT_STATUS_OK;
97
98 error:
99         talloc_destroy(go->mem_ctx);
100         *obj = NULL;
101         return ret;
102 }
103
104 NTSTATUS gums_create_privilege(GUMS_PRIVILEGE **priv)
105 {
106         TALLOC_CTX *mem_ctx;
107         GUMS_PRIVILEGE *pri;
108
109         mem_ctx = talloc_init("gums_create_privilege");
110         if (!mem_ctx) {
111                 DEBUG(0, ("gums_create_privilege: Out of memory!\n"));
112                 *priv = NULL;
113                 return NT_STATUS_NO_MEMORY;
114         }
115
116         pri = talloc_zero(mem_ctx, sizeof(GUMS_PRIVILEGE));
117         if (!pri) {
118                 DEBUG(0, ("gums_create_privilege: Out of memory!\n"));
119                 talloc_destroy(mem_ctx);
120                 *priv = NULL;
121                 return NT_STATUS_NO_MEMORY;
122         }
123
124         pri->mem_ctx = mem_ctx;
125         pri->version = GUMS_PRIVILEGE_VERSION;
126
127         *priv = pri;
128         return NT_STATUS_OK;
129 }
130
131 NTSTATUS gums_destroy_object(GUMS_OBJECT **obj)
132 {
133         if (!obj || !(*obj))
134                 return NT_STATUS_INVALID_PARAMETER;
135
136         if ((*obj)->mem_ctx)
137                 talloc_destroy((*obj)->mem_ctx);
138         *obj = NULL;
139
140         return NT_STATUS_OK;
141 }
142
143 NTSTATUS gums_destroy_privilege(GUMS_PRIVILEGE **priv)
144 {
145         if (!priv || !(*priv))
146                 return NT_STATUS_INVALID_PARAMETER;
147
148         if ((*priv)->mem_ctx)
149                 talloc_destroy((*priv)->mem_ctx);
150         *priv = NULL;
151
152         return NT_STATUS_OK;
153 }
154
155 void gums_reset_object(GUMS_OBJECT *go)
156 {
157         go->seq_num = 0;
158         go->sid = NULL;
159         go->name = NULL;
160         go->description = NULL;
161
162         switch(go->type) {
163                 case GUMS_OBJ_DOMAIN:
164                         memset(go->domain, 0, sizeof(GUMS_DOMAIN));
165                         break;
166
167 /*
168                 case GUMS_OBJ_WORKSTATION_TRUST:
169                 case GUMS_OBJ_SERVER_TRUST:
170                 case GUMS_OBJ_DOMAIN_TRUST:
171 */
172                 case GUMS_OBJ_NORMAL_USER:
173                         memset(go->user, 0, sizeof(GUMS_USER));
174                         gums_set_user_acct_ctrl(go, ACB_NORMAL);
175                         break;
176
177                 case GUMS_OBJ_GROUP:
178                 case GUMS_OBJ_ALIAS:
179                         memset(go->group, 0, sizeof(GUMS_GROUP));
180                         break;
181
182                 default:
183                         return;
184         }
185 }
186
187 uint32 gums_get_object_type(const GUMS_OBJECT *obj)
188 {
189         if (!obj)
190                 return 0;
191
192         return obj->type;
193 }
194
195 uint32 gums_get_object_seq_num(const GUMS_OBJECT *obj)
196 {
197         if (!obj)
198                 return 0;
199
200         return obj->seq_num;
201 }
202
203 uint32 gums_get_object_version(const GUMS_OBJECT *obj)
204 {
205         if (!obj)
206                 return 0;
207
208         return obj->version;
209 }
210
211 const SEC_DESC *gums_get_sec_desc(const GUMS_OBJECT *obj)
212 {
213         if (!obj)
214                 return NULL;
215
216         return obj->sec_desc;
217 }
218
219 const DOM_SID *gums_get_object_sid(const GUMS_OBJECT *obj)
220 {
221         if (!obj)
222                 return NULL;
223
224         return obj->sid;
225 }
226
227 const char *gums_get_object_name(const GUMS_OBJECT *obj)
228 {
229         if (!obj)
230                 return NULL;
231
232         return obj->name;
233 }
234
235 const char *gums_get_object_description(const GUMS_OBJECT *obj)
236 {
237         if (!obj)
238                 return NULL;
239
240         return obj->description;
241 }
242
243 NTSTATUS gums_set_object_seq_num(GUMS_OBJECT *obj, uint32 seq_num)
244 {
245         if (!obj)
246                 return NT_STATUS_INVALID_PARAMETER;
247
248         obj->seq_num = seq_num;
249         return NT_STATUS_OK;
250 }
251
252 NTSTATUS gums_set_object_version(GUMS_OBJECT *obj, uint32 version)
253 {
254         if (!obj)
255                 return NT_STATUS_INVALID_PARAMETER;
256
257         obj->version = version;
258         return NT_STATUS_OK;
259 }
260
261 NTSTATUS gums_set_sec_desc(GUMS_OBJECT *obj, const SEC_DESC *sec_desc)
262 {
263         if (!obj || !sec_desc)
264                 return NT_STATUS_INVALID_PARAMETER;
265
266         obj->sec_desc = dup_sec_desc(obj->mem_ctx, sec_desc);
267         if (!(obj->sec_desc)) return NT_STATUS_UNSUCCESSFUL;
268         return NT_STATUS_OK;
269 }
270
271 NTSTATUS gums_set_object_sid(GUMS_OBJECT *obj, const DOM_SID *sid)
272 {
273         if (!obj || !sid)
274                 return NT_STATUS_INVALID_PARAMETER;
275
276         obj->sid = sid_dup_talloc(obj->mem_ctx, sid);
277         if (!(obj->sid)) return NT_STATUS_UNSUCCESSFUL;
278         return NT_STATUS_OK;
279 }
280
281 NTSTATUS gums_set_object_name(GUMS_OBJECT *obj, const char *name)
282 {
283         if (!obj || !name)
284                 return NT_STATUS_INVALID_PARAMETER;
285
286         obj->name = (char *)talloc_strdup(obj->mem_ctx, name);
287         if (!(obj->name)) return NT_STATUS_UNSUCCESSFUL;
288         return NT_STATUS_OK;
289 }
290
291 NTSTATUS gums_set_object_description(GUMS_OBJECT *obj, const char *description)
292 {
293         if (!obj || !description)
294                 return NT_STATUS_INVALID_PARAMETER;
295
296         obj->description = (char *)talloc_strdup(obj->mem_ctx, description);
297         if (!(obj->description)) return NT_STATUS_UNSUCCESSFUL;
298         return NT_STATUS_OK;
299 }
300
301 /*
302 NTSTATUS gums_get_object_privileges(PRIVILEGE_SET **priv_set, const GUMS_OBJECT *obj)
303 {
304         if (!priv_set)
305                 return NT_STATUS_INVALID_PARAMETER;
306
307         *priv_set = obj->priv_set;
308         return NT_STATUS_OK;
309 }
310 */
311
312 uint32 gums_get_domain_next_rid(const GUMS_OBJECT *obj)
313 {
314         if (obj->type != GUMS_OBJ_DOMAIN)
315                 return -1;
316
317         return obj->domain->next_rid;
318 }
319
320 NTSTATUS gums_set_domain_next_rid(GUMS_OBJECT *obj, uint32 rid)
321 {
322         if (!obj)
323                 return NT_STATUS_INVALID_PARAMETER;
324
325         if (obj->type != GUMS_OBJ_DOMAIN)
326                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
327
328         obj->domain->next_rid = rid;
329         return NT_STATUS_OK;
330 }
331
332 /* User specific functions */
333
334 const DOM_SID *gums_get_user_pri_group(const GUMS_OBJECT *obj)
335 {
336         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
337                 return NULL;
338
339         return  obj->user->group_sid;
340 }
341
342 const DATA_BLOB gums_get_user_nt_pwd(const GUMS_OBJECT *obj)
343 {
344         fstring p;
345
346         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
347                 return data_blob(NULL, 0);
348
349         pdb_sethexpwd(p, (unsigned char *)(obj->user->nt_pw.data), 0);
350         DEBUG(100, ("Reading NT Password=[%s]\n", p));
351
352         return obj->user->nt_pw;
353 }
354
355 const DATA_BLOB gums_get_user_lm_pwd(const GUMS_OBJECT *obj)
356
357         fstring p;
358
359         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
360                 return data_blob(NULL, 0);
361
362         pdb_sethexpwd(p, (unsigned char *)(obj->user->lm_pw.data), 0);
363         DEBUG(100, ("Reading LM Password=[%s]\n", p));
364
365         return obj->user->lm_pw;
366 }
367
368 const char *gums_get_user_fullname(const GUMS_OBJECT *obj)
369 {
370         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
371                 return NULL;
372
373         return obj->user->full_name;
374 }
375
376 const char *gums_get_user_homedir(const GUMS_OBJECT *obj)
377 {
378         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
379                 return NULL;
380
381         return obj->user->home_dir;
382 }
383
384 const char *gums_get_user_dir_drive(const GUMS_OBJECT *obj)
385 {
386         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
387                 return NULL;
388
389         return obj->user->dir_drive;
390 }
391
392 const char *gums_get_user_profile_path(const GUMS_OBJECT *obj)
393 {
394         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
395                 return NULL;
396
397         return obj->user->profile_path;
398 }
399
400 const char *gums_get_user_logon_script(const GUMS_OBJECT *obj)
401 {
402         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
403                 return NULL;
404
405         return obj->user->logon_script;
406 }
407
408 const char *gums_get_user_workstations(const GUMS_OBJECT *obj)
409 {
410         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
411                 return NULL;
412
413         return obj->user->workstations;
414 }
415
416 const char *gums_get_user_unknown_str(const GUMS_OBJECT *obj)
417 {
418         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
419                 return NULL;
420
421         return obj->user->unknown_str;
422 }
423
424 const char *gums_get_user_munged_dial(const GUMS_OBJECT *obj)
425 {
426         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
427                 return NULL;
428
429         return obj->user->munged_dial;
430 }
431
432 NTTIME gums_get_user_logon_time(const GUMS_OBJECT *obj)
433 {
434         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) {
435                 NTTIME null_time;
436                 init_nt_time(&null_time);
437                 return null_time;
438         }
439
440         return obj->user->logon_time;
441 }
442
443 NTTIME gums_get_user_logoff_time(const GUMS_OBJECT *obj)
444 {
445         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) {
446                 NTTIME null_time;
447                 init_nt_time(&null_time);
448                 return null_time;
449         }
450
451         return obj->user->logoff_time;
452 }
453
454 NTTIME gums_get_user_kickoff_time(const GUMS_OBJECT *obj)
455 {
456         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) {
457                 NTTIME null_time;
458                 init_nt_time(&null_time);
459                 return null_time;
460         }
461
462         return obj->user->kickoff_time;
463 }
464
465 NTTIME gums_get_user_pass_last_set_time(const GUMS_OBJECT *obj)
466 {
467         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) {
468                 NTTIME null_time;
469                 init_nt_time(&null_time);
470                 return null_time;
471         }
472
473         return obj->user->pass_last_set_time;
474 }
475
476 NTTIME gums_get_user_pass_can_change_time(const GUMS_OBJECT *obj)
477 {
478         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) {
479                 NTTIME null_time;
480                 init_nt_time(&null_time);
481                 return null_time;
482         }
483
484         return obj->user->pass_can_change_time;
485 }
486
487 NTTIME gums_get_user_pass_must_change_time(const GUMS_OBJECT *obj)
488 {
489         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER) {
490                 NTTIME null_time;
491                 init_nt_time(&null_time);
492                 return null_time;
493         }
494
495         return obj->user->pass_must_change_time;
496 }
497
498 uint16 gums_get_user_acct_ctrl(const GUMS_OBJECT *obj)
499 {
500         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
501                 return 0;
502
503         return obj->user->acct_ctrl;
504 }
505
506 uint16 gums_get_user_logon_divs(const GUMS_OBJECT *obj)
507 {
508         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
509                 return 0;
510
511         return obj->user->logon_divs;
512 }
513
514 uint32 gums_get_user_hours_len(const GUMS_OBJECT *obj)
515 {
516         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
517                 return 0;
518
519         return obj->user->hours_len;
520 }
521
522 const uint8 *gums_get_user_hours(const GUMS_OBJECT *obj)
523 {
524         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
525                 return NULL;
526
527         return obj->user->hours;
528 }
529
530 uint32 gums_get_user_unknown_3(const GUMS_OBJECT *obj)
531 {
532         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
533                 return 0;
534
535         return obj->user->unknown_3;
536 }
537
538 uint16 gums_get_user_bad_password_count(const GUMS_OBJECT *obj)
539 {
540         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
541                 return 0;
542
543         return obj->user->bad_password_count;
544 }
545
546 uint16 gums_get_user_logon_count(const GUMS_OBJECT *obj)
547 {
548         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
549                 return 0;
550
551         return obj->user->logon_count;
552 }
553
554 uint32 gums_get_user_unknown_6(const GUMS_OBJECT *obj)
555 {
556         if (!obj || obj->type != GUMS_OBJ_NORMAL_USER)
557                 return 0;
558
559         return obj->user->unknown_6;
560 }
561
562 NTSTATUS gums_set_user_pri_group(GUMS_OBJECT *obj, const DOM_SID *sid)
563 {
564         if (!obj || !sid)
565                 return NT_STATUS_INVALID_PARAMETER;
566
567         if (obj->type != GUMS_OBJ_NORMAL_USER)
568                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
569
570         obj->user->group_sid = sid_dup_talloc(obj->mem_ctx, sid);
571         if (!(obj->user->group_sid)) return NT_STATUS_NO_MEMORY;
572         return NT_STATUS_OK;
573 }
574
575 NTSTATUS gums_set_user_nt_pwd(GUMS_OBJECT *obj, const DATA_BLOB nt_pwd)
576 {
577         fstring p;
578         unsigned char r[16];
579
580         if (!obj)
581                 return NT_STATUS_INVALID_PARAMETER;
582
583         if (obj->type != GUMS_OBJ_NORMAL_USER)
584                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
585
586         obj->user->nt_pw = data_blob_talloc(obj->mem_ctx, nt_pwd.data, nt_pwd.length);
587
588         memcpy(r, nt_pwd.data, 16);
589         pdb_sethexpwd(p, r, 0);
590         DEBUG(100, ("Setting NT Password=[%s]\n", p));
591
592         return NT_STATUS_OK;
593 }
594
595 NTSTATUS gums_set_user_lm_pwd(GUMS_OBJECT *obj, const DATA_BLOB lm_pwd)
596 {
597         fstring p;
598         unsigned char r[16];
599
600         if (!obj)
601                 return NT_STATUS_INVALID_PARAMETER;
602
603         if (obj->type != GUMS_OBJ_NORMAL_USER)
604                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
605
606         obj->user->lm_pw = data_blob_talloc(obj->mem_ctx, lm_pwd.data, lm_pwd.length);
607
608         memcpy(r, lm_pwd.data, 16);
609         pdb_sethexpwd(p, r, 0);
610         DEBUG(100, ("Setting LM Password=[%s]\n", p));
611
612         return NT_STATUS_OK;
613 }
614
615 NTSTATUS gums_set_user_fullname(GUMS_OBJECT *obj, const char *fullname)
616 {
617         if (!obj || !fullname)
618                 return NT_STATUS_INVALID_PARAMETER;
619
620         if (obj->type != GUMS_OBJ_NORMAL_USER)
621                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
622
623         obj->user->full_name = (char *)talloc_strdup(obj->mem_ctx, fullname);
624         if (!(obj->user->full_name)) return NT_STATUS_NO_MEMORY;
625         return NT_STATUS_OK;
626 }
627
628 NTSTATUS gums_set_user_homedir(GUMS_OBJECT *obj, const char *homedir)
629 {
630         if (!obj || !homedir)
631                 return NT_STATUS_INVALID_PARAMETER;
632
633         if (obj->type != GUMS_OBJ_NORMAL_USER)
634                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
635
636         obj->user->home_dir = (char *)talloc_strdup(obj->mem_ctx, homedir);
637         if (!(obj->user->home_dir)) return NT_STATUS_NO_MEMORY;
638         return NT_STATUS_OK;
639 }
640
641 NTSTATUS gums_set_user_dir_drive(GUMS_OBJECT *obj, const char *dir_drive)
642 {
643         if (!obj || !dir_drive)
644                 return NT_STATUS_INVALID_PARAMETER;
645
646         if (obj->type != GUMS_OBJ_NORMAL_USER)
647                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
648
649         obj->user->dir_drive = (char *)talloc_strdup(obj->mem_ctx, dir_drive);
650         if (!(obj->user->dir_drive)) return NT_STATUS_NO_MEMORY;
651         return NT_STATUS_OK;
652 }
653
654 NTSTATUS gums_set_user_logon_script(GUMS_OBJECT *obj, const char *logon_script)
655 {
656         if (!obj || !logon_script)
657                 return NT_STATUS_INVALID_PARAMETER;
658
659         if (obj->type != GUMS_OBJ_NORMAL_USER)
660                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
661
662         obj->user->logon_script = (char *)talloc_strdup(obj->mem_ctx, logon_script);
663         if (!(obj->user->logon_script)) return NT_STATUS_NO_MEMORY;
664         return NT_STATUS_OK;
665 }
666
667 NTSTATUS gums_set_user_profile_path(GUMS_OBJECT *obj, const char *profile_path)
668 {
669         if (!obj || !profile_path)
670                 return NT_STATUS_INVALID_PARAMETER;
671
672         if (obj->type != GUMS_OBJ_NORMAL_USER)
673                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
674
675         obj->user->profile_path = (char *)talloc_strdup(obj->mem_ctx, profile_path);
676         if (!(obj->user->profile_path)) return NT_STATUS_NO_MEMORY;
677         return NT_STATUS_OK;
678 }
679
680 NTSTATUS gums_set_user_workstations(GUMS_OBJECT *obj, const char *workstations)
681 {
682         if (!obj || !workstations)
683                 return NT_STATUS_INVALID_PARAMETER;
684
685         if (obj->type != GUMS_OBJ_NORMAL_USER)
686                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
687
688         obj->user->workstations = (char *)talloc_strdup(obj->mem_ctx, workstations);
689         if (!(obj->user->workstations)) return NT_STATUS_NO_MEMORY;
690         return NT_STATUS_OK;
691 }
692
693 NTSTATUS gums_set_user_unknown_str(GUMS_OBJECT *obj, const char *unknown_str)
694 {
695         if (!obj || !unknown_str)
696                 return NT_STATUS_INVALID_PARAMETER;
697
698         if (obj->type != GUMS_OBJ_NORMAL_USER)
699                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
700
701         obj->user->unknown_str = (char *)talloc_strdup(obj->mem_ctx, unknown_str);
702         if (!(obj->user->unknown_str)) return NT_STATUS_NO_MEMORY;
703         return NT_STATUS_OK;
704 }
705
706 NTSTATUS gums_set_user_munged_dial(GUMS_OBJECT *obj, const char *munged_dial)
707 {
708         if (!obj || !munged_dial)
709                 return NT_STATUS_INVALID_PARAMETER;
710
711         if (obj->type != GUMS_OBJ_NORMAL_USER)
712                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
713
714         obj->user->munged_dial = (char *)talloc_strdup(obj->mem_ctx, munged_dial);
715         if (!(obj->user->munged_dial)) return NT_STATUS_NO_MEMORY;
716         return NT_STATUS_OK;
717 }
718
719 NTSTATUS gums_set_user_logon_time(GUMS_OBJECT *obj, NTTIME logon_time)
720 {
721         if (!obj)
722                 return NT_STATUS_INVALID_PARAMETER;
723
724         if (obj->type != GUMS_OBJ_NORMAL_USER)
725                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
726
727         obj->user->logon_time = logon_time;
728         return NT_STATUS_OK;
729 }
730
731 NTSTATUS gums_set_user_logoff_time(GUMS_OBJECT *obj, NTTIME logoff_time)
732 {
733         if (!obj)
734                 return NT_STATUS_INVALID_PARAMETER;
735
736         if (obj->type != GUMS_OBJ_NORMAL_USER)
737                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
738
739         obj->user->logoff_time = logoff_time;
740         return NT_STATUS_OK;
741 }
742
743 NTSTATUS gums_set_user_kickoff_time(GUMS_OBJECT *obj, NTTIME kickoff_time)
744 {
745         if (!obj)
746                 return NT_STATUS_INVALID_PARAMETER;
747
748         if (obj->type != GUMS_OBJ_NORMAL_USER)
749                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
750
751         obj->user->kickoff_time = kickoff_time;
752         return NT_STATUS_OK;
753 }
754
755 NTSTATUS gums_set_user_pass_last_set_time(GUMS_OBJECT *obj, NTTIME pass_last_set_time)
756 {
757         if (!obj)
758                 return NT_STATUS_INVALID_PARAMETER;
759
760         if (obj->type != GUMS_OBJ_NORMAL_USER)
761                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
762
763         obj->user->pass_last_set_time = pass_last_set_time;
764         return NT_STATUS_OK;
765 }
766
767 NTSTATUS gums_set_user_pass_can_change_time(GUMS_OBJECT *obj, NTTIME pass_can_change_time)
768 {
769         if (!obj)
770                 return NT_STATUS_INVALID_PARAMETER;
771
772         if (obj->type != GUMS_OBJ_NORMAL_USER)
773                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
774
775         obj->user->pass_can_change_time = pass_can_change_time;
776         return NT_STATUS_OK;
777 }
778
779 NTSTATUS gums_set_user_pass_must_change_time(GUMS_OBJECT *obj, NTTIME pass_must_change_time)
780 {
781         if (!obj)
782                 return NT_STATUS_INVALID_PARAMETER;
783
784         if (obj->type != GUMS_OBJ_NORMAL_USER)
785                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
786
787         obj->user->pass_must_change_time = pass_must_change_time;
788         return NT_STATUS_OK;
789 }
790
791 NTSTATUS gums_set_user_acct_ctrl(GUMS_OBJECT *obj, uint16 acct_ctrl)
792 {
793         if (!obj)
794                 return NT_STATUS_INVALID_PARAMETER;
795
796         if (obj->type != GUMS_OBJ_NORMAL_USER)
797                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
798
799         obj->user->acct_ctrl = acct_ctrl;
800         return NT_STATUS_OK;
801 }
802
803 NTSTATUS gums_set_user_logon_divs(GUMS_OBJECT *obj, uint16 logon_divs)
804 {
805         if (!obj)
806                 return NT_STATUS_INVALID_PARAMETER;
807
808         if (obj->type != GUMS_OBJ_NORMAL_USER)
809                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
810
811         obj->user->logon_divs = logon_divs;
812         return NT_STATUS_OK;
813 }
814
815 NTSTATUS gums_set_user_hours(GUMS_OBJECT *obj, uint32 hours_len, const uint8 *hours)
816 {
817         if (!obj || !hours)
818                 return NT_STATUS_INVALID_PARAMETER;
819
820         if (obj->type != GUMS_OBJ_NORMAL_USER)
821                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
822
823         obj->user->hours_len = hours_len;
824         if (hours_len == 0)
825                 DEBUG(10, ("gums_set_user_hours: Warning, hours_len is zero!\n"));
826
827         obj->user->hours = (uint8 *)talloc(obj->mem_ctx, MAX_HOURS_LEN);
828         if (!(obj->user->hours))
829                 return NT_STATUS_NO_MEMORY;
830         if (hours_len)
831                 memcpy(obj->user->hours, hours, hours_len);
832
833         return NT_STATUS_OK;
834 }
835
836 NTSTATUS gums_set_user_unknown_3(GUMS_OBJECT *obj, uint32 unknown_3)
837 {
838         if (!obj)
839                 return NT_STATUS_INVALID_PARAMETER;
840
841         if (obj->type != GUMS_OBJ_NORMAL_USER)
842                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
843
844         obj->user->unknown_3 = unknown_3;
845         return NT_STATUS_OK;
846 }
847
848 NTSTATUS gums_set_user_bad_password_count(GUMS_OBJECT *obj, uint16 bad_password_count)
849 {
850         if (!obj)
851                 return NT_STATUS_INVALID_PARAMETER;
852
853         if (obj->type != GUMS_OBJ_NORMAL_USER)
854                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
855
856         obj->user->bad_password_count = bad_password_count;
857         return NT_STATUS_OK;
858 }
859
860 NTSTATUS gums_set_user_logon_count(GUMS_OBJECT *obj, uint16 logon_count)
861 {
862         if (!obj)
863                 return NT_STATUS_INVALID_PARAMETER;
864
865         if (obj->type != GUMS_OBJ_NORMAL_USER)
866                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
867
868         obj->user->logon_count = logon_count;
869         return NT_STATUS_OK;
870 }
871
872 NTSTATUS gums_set_user_unknown_6(GUMS_OBJECT *obj, uint32 unknown_6)
873 {
874         if (!obj)
875                 return NT_STATUS_INVALID_PARAMETER;
876
877         if (obj->type != GUMS_OBJ_NORMAL_USER)
878                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
879
880         obj->user->unknown_6 = unknown_6;
881         return NT_STATUS_OK;
882 }
883
884 /* Group specific functions */
885
886 const DOM_SID *gums_get_group_members(int *count, const GUMS_OBJECT *obj)
887 {
888         if (!count || !obj || !(obj->type == GUMS_OBJ_GROUP || obj->type == GUMS_OBJ_ALIAS)) {
889                 *count = -1;
890                 return NULL;
891         }
892
893         *count = obj->group->count;
894         return obj->group->members;
895 }
896
897 NTSTATUS gums_set_group_members(GUMS_OBJECT *obj, uint32 count, DOM_SID *members)
898 {
899         uint32 n;
900
901         if (!obj || ((count > 0) && !members))
902                 return NT_STATUS_INVALID_PARAMETER;
903
904         if (obj->type != GUMS_OBJ_GROUP &&
905                 obj->type != GUMS_OBJ_ALIAS)
906                         return NT_STATUS_OBJECT_TYPE_MISMATCH;
907
908         obj->group->count = count;
909
910         if (count) {
911                 obj->group->members = (DOM_SID *)talloc(obj->mem_ctx, count * sizeof(DOM_SID));
912                 if (!(obj->group->members)) {
913                         return NT_STATUS_NO_MEMORY;
914                 }
915
916
917                 n = 0;
918                 do {
919                         sid_copy(&(obj->group->members[n]), &(members[n]));
920                         n++;
921                 } while (n < count);
922         } else {
923                 obj->group->members = 0;
924         }
925
926         return NT_STATUS_OK;
927 }
928
929 /* Privilege specific functions */
930
931 const LUID_ATTR *gums_get_priv_luid_attr(const GUMS_PRIVILEGE *priv)
932 {
933         if (!priv) {
934                 return NULL;
935         }
936
937         return priv->privilege;
938 }
939
940 const DOM_SID *gums_get_priv_members(int *count, const GUMS_PRIVILEGE *priv)
941 {
942         if (!count || !priv) {
943                 *count = -1;
944                 return NULL;
945         }
946
947         *count = priv->count;
948         return priv->members;
949 }
950
951 NTSTATUS gums_set_priv_luid_attr(GUMS_PRIVILEGE *priv, LUID_ATTR *luid_attr)
952 {
953         if (!luid_attr || !priv)
954                 return NT_STATUS_INVALID_PARAMETER;
955
956         priv->privilege = (LUID_ATTR *)talloc_memdup(priv->mem_ctx, luid_attr, sizeof(LUID_ATTR));
957         if (!(priv->privilege)) return NT_STATUS_NO_MEMORY;
958         return NT_STATUS_OK;
959 }
960
961 NTSTATUS gums_set_priv_members(GUMS_PRIVILEGE *priv, uint32 count, DOM_SID *members)
962 {
963         uint32 n;
964
965         if (!priv || !members || !members)
966                 return NT_STATUS_INVALID_PARAMETER;
967
968         priv->count = count;
969         priv->members = (DOM_SID *)talloc(priv->mem_ctx, count * sizeof(DOM_SID));
970         if (!(priv->members))
971                 return NT_STATUS_NO_MEMORY;
972
973         n = 0;
974         do {
975                 sid_copy(&(priv->members[n]), &(members[n]));
976                 n++;
977         } while (n < count);
978
979         return NT_STATUS_OK;
980 }
981
982 /* data_store set functions */
983
984 NTSTATUS gums_create_commit_set(GUMS_COMMIT_SET **com_set, DOM_SID *sid, uint32 type)
985 {
986         TALLOC_CTX *mem_ctx;
987
988         mem_ctx = talloc_init("commit_set");
989         if (mem_ctx == NULL)
990                 return NT_STATUS_NO_MEMORY;
991
992         *com_set = (GUMS_COMMIT_SET *)talloc_zero(mem_ctx, sizeof(GUMS_COMMIT_SET));
993         if (*com_set == NULL) {
994                 talloc_destroy(mem_ctx);
995                 return NT_STATUS_NO_MEMORY;
996         }
997
998         (*com_set)->mem_ctx = mem_ctx;
999         (*com_set)->type = type;
1000         sid_copy(&((*com_set)->sid), sid);
1001
1002         return NT_STATUS_OK;
1003 }
1004
1005 NTSTATUS gums_cs_grow_data_set(GUMS_COMMIT_SET *com_set, int size)
1006 {
1007         GUMS_DATA_SET *data_set;
1008
1009         com_set->count = com_set->count + size;
1010         if (com_set->count == size) { /* data set is empty*/
1011                 data_set = (GUMS_DATA_SET *)talloc_zero(com_set->mem_ctx, sizeof(GUMS_DATA_SET));
1012         } else {
1013                 data_set = (GUMS_DATA_SET *)talloc_realloc(com_set->mem_ctx, com_set->data, sizeof(GUMS_DATA_SET) * com_set->count);
1014         }
1015         if (data_set == NULL)
1016                 return NT_STATUS_NO_MEMORY;
1017
1018         com_set->data = data_set;
1019
1020         return NT_STATUS_OK;
1021 }
1022
1023 NTSTATUS gums_cs_set_sec_desc(GUMS_COMMIT_SET *com_set, SEC_DESC *sec_desc)
1024 {
1025         NTSTATUS ret;
1026         GUMS_DATA_SET *data_set;
1027         SEC_DESC *new_sec_desc;
1028
1029         if (!com_set || !sec_desc)
1030                 return NT_STATUS_INVALID_PARAMETER;
1031
1032         if (!NT_STATUS_IS_OK(ret = gums_cs_grow_data_set(com_set, 1)))
1033                 return ret;
1034
1035         data_set = &((com_set->data)[com_set->count - 1]);
1036         
1037         data_set->type = GUMS_SET_SEC_DESC;
1038         new_sec_desc = dup_sec_desc(com_set->mem_ctx, sec_desc);
1039         if (new_sec_desc == NULL)
1040                 return NT_STATUS_NO_MEMORY;
1041
1042         (SEC_DESC *)(data_set->data) = new_sec_desc;
1043
1044         return NT_STATUS_OK;
1045 }
1046
1047 /*
1048 NTSTATUS gums_cs_add_privilege(GUMS_PRIV_COMMIT_SET *com_set, LUID_ATTR priv)
1049 {
1050         NTSTATUS ret;
1051         GUMS_DATA_SET *data_set;
1052         LUID_ATTR *new_priv;
1053
1054         if (!com_set)
1055                 return NT_STATUS_INVALID_PARAMETER;
1056
1057         if (!NT_STATUS_OK(ret = gums_pcs_grow_data_set(com_set, 1)))
1058                 return ret;
1059
1060         data_set = ((com_set->data)[com_set->count - 1]);
1061         
1062         data_set->type = GUMS_ADD_PRIVILEGE;
1063         if (!NT_STATUS_IS_OK(ret = dupalloc_luid_attr(com_set->mem_ctx, &new_priv, priv)))
1064                 return ret;
1065
1066         (SEC_DESC *)(data_set->data) = new_priv;
1067
1068         return NT_STATUS_OK;    
1069 }
1070
1071 NTSTATUS gums_cs_del_privilege(GUMS_PRIV_COMMIT_SET *com_set, LUID_ATTR priv)
1072 {
1073         NTSTATUS ret;
1074         GUMS_DATA_SET *data_set;
1075         LUID_ATTR *new_priv;
1076
1077         if (!com_set)
1078                 return NT_STATUS_INVALID_PARAMETER;
1079
1080         if (!NT_STATUS_OK(ret = gums_pcs_grow_data_set(com_set, 1)))
1081                 return ret;
1082
1083         data_set = ((com_set->data)[com_set->count - 1]);
1084         
1085         data_set->type = GUMS_DEL_PRIVILEGE;
1086         if (!NT_STATUS_IS_OK(ret = dupalloc_luid_attr(com_set->mem_ctx, &new_priv, priv)))
1087                 return ret;
1088
1089         (SEC_DESC *)(data_set->data) = new_priv;
1090
1091         return NT_STATUS_OK;    
1092 }
1093
1094 NTSTATUS gums_cs_set_privilege_set(GUMS_PRIV_COMMIT_SET *com_set, PRIVILEGE_SET *priv_set)
1095 {
1096         NTSTATUS ret;
1097         GUMS_DATA_SET *data_set;
1098         PRIVILEGE_SET *new_priv_set;
1099
1100         if (!com_set || !priv_set)
1101                 return NT_STATUS_INVALID_PARAMETER;
1102
1103         if (!NT_STATUS_OK(ret = gums_pcs_grow_data_set(com_set, 1)))
1104                 return ret;
1105
1106         data_set = ((com_set->data)[com_set->count - 1]);
1107         
1108         data_set->type = GUMS_SET_PRIVILEGE;
1109         if (!NT_STATUS_IS_OK(ret = init_priv_set_with_ctx(com_set->mem_ctx, &new_priv_set)))
1110                 return ret;
1111                 
1112         if (!NT_STATUS_IS_OK(ret = dup_priv_set(new_priv_set, priv_set)))
1113                 return ret;
1114
1115         (SEC_DESC *)(data_set->data) = new_priv_set;
1116
1117         return NT_STATUS_OK;
1118 }
1119 */
1120
1121 NTSTATUS gums_cs_set_string(GUMS_COMMIT_SET *com_set, uint32 type, char *str)
1122 {
1123         NTSTATUS ret;
1124         GUMS_DATA_SET *data_set;
1125         char *new_str;
1126
1127         if (!com_set || !str || type < GUMS_SET_NAME || type > GUMS_SET_MUNGED_DIAL)
1128                 return NT_STATUS_INVALID_PARAMETER;
1129
1130         if (!NT_STATUS_IS_OK(ret = gums_cs_grow_data_set(com_set, 1)))
1131                 return ret;
1132
1133         data_set = &((com_set->data)[com_set->count - 1]);
1134         
1135         data_set->type = type;
1136         new_str = talloc_strdup(com_set->mem_ctx, str);
1137         if (new_str == NULL)
1138                 return NT_STATUS_NO_MEMORY;
1139
1140         (char *)(data_set->data) = new_str;
1141
1142         return NT_STATUS_OK;
1143 }
1144
1145 NTSTATUS gums_cs_set_name(GUMS_COMMIT_SET *com_set, char *name)
1146 {
1147         return gums_cs_set_string(com_set, GUMS_SET_NAME, name);
1148 }
1149
1150 NTSTATUS gums_cs_set_description(GUMS_COMMIT_SET *com_set, char *desc)
1151 {
1152         return gums_cs_set_string(com_set, GUMS_SET_DESCRIPTION, desc);
1153 }
1154
1155 NTSTATUS gums_cs_set_full_name(GUMS_COMMIT_SET *com_set, char *full_name)
1156 {
1157         if (com_set->type != GUMS_OBJ_NORMAL_USER)
1158                 return NT_STATUS_INVALID_PARAMETER;
1159
1160         return gums_cs_set_string(com_set, GUMS_SET_NAME, full_name);
1161 }
1162
1163 NTSTATUS gums_cs_set_home_directory(GUMS_COMMIT_SET *com_set, char *home_dir)
1164 {
1165         if (com_set->type != GUMS_OBJ_NORMAL_USER)
1166                 return NT_STATUS_INVALID_PARAMETER;
1167
1168         return gums_cs_set_string(com_set, GUMS_SET_NAME, home_dir);
1169 }
1170
1171 NTSTATUS gums_cs_set_drive(GUMS_COMMIT_SET *com_set, char *drive)
1172 {
1173         if (com_set->type != GUMS_OBJ_NORMAL_USER)
1174                 return NT_STATUS_INVALID_PARAMETER;
1175
1176         return gums_cs_set_string(com_set, GUMS_SET_NAME, drive);
1177 }
1178
1179 NTSTATUS gums_cs_set_logon_script(GUMS_COMMIT_SET *com_set, char *logon_script)
1180 {
1181         if (com_set->type != GUMS_OBJ_NORMAL_USER)
1182                 return NT_STATUS_INVALID_PARAMETER;
1183
1184         return gums_cs_set_string(com_set, GUMS_SET_NAME, logon_script);
1185 }
1186
1187 NTSTATUS gums_cs_set_profile_path(GUMS_COMMIT_SET *com_set, char *prof_path)
1188 {
1189         if (com_set->type != GUMS_OBJ_NORMAL_USER)
1190                 return NT_STATUS_INVALID_PARAMETER;
1191
1192         return gums_cs_set_string(com_set, GUMS_SET_NAME, prof_path);
1193 }
1194
1195 NTSTATUS gums_cs_set_workstations(GUMS_COMMIT_SET *com_set, char *wks)
1196 {
1197         if (com_set->type != GUMS_OBJ_NORMAL_USER)
1198                 return NT_STATUS_INVALID_PARAMETER;
1199
1200         return gums_cs_set_string(com_set, GUMS_SET_NAME, wks);
1201 }
1202
1203 NTSTATUS gums_cs_set_unknown_string(GUMS_COMMIT_SET *com_set, char *unkn_str)
1204 {
1205         if (com_set->type != GUMS_OBJ_NORMAL_USER)
1206                 return NT_STATUS_INVALID_PARAMETER;
1207
1208         return gums_cs_set_string(com_set, GUMS_SET_NAME, unkn_str);
1209 }
1210
1211 NTSTATUS gums_cs_set_munged_dial(GUMS_COMMIT_SET *com_set, char *munged_dial)
1212 {
1213         if (com_set->type != GUMS_OBJ_NORMAL_USER)
1214                 return NT_STATUS_INVALID_PARAMETER;
1215
1216         return gums_cs_set_string(com_set, GUMS_SET_NAME, munged_dial);
1217 }
1218
1219 NTSTATUS gums_cs_set_nttime(GUMS_COMMIT_SET *com_set, uint32 type, NTTIME *nttime)
1220 {
1221         NTSTATUS ret;
1222         GUMS_DATA_SET *data_set;
1223         NTTIME *new_time;
1224
1225         if (!com_set || !nttime || type < GUMS_SET_LOGON_TIME || type > GUMS_SET_PASS_MUST_CHANGE_TIME)
1226                 return NT_STATUS_INVALID_PARAMETER;
1227
1228         if (!NT_STATUS_IS_OK(ret = gums_cs_grow_data_set(com_set, 1)))
1229                 return ret;
1230
1231         data_set = &((com_set->data)[com_set->count - 1]);
1232         
1233         data_set->type = type;
1234         new_time = talloc(com_set->mem_ctx, sizeof(NTTIME));
1235         if (new_time == NULL)
1236                 return NT_STATUS_NO_MEMORY;
1237
1238         new_time->low = nttime->low;
1239         new_time->high = nttime->high;
1240         (char *)(data_set->data) = new_time;
1241
1242         return NT_STATUS_OK;
1243 }
1244
1245 NTSTATUS gums_cs_set_logon_time(GUMS_COMMIT_SET *com_set, NTTIME *logon_time)
1246 {
1247         if (com_set->type != GUMS_OBJ_NORMAL_USER)
1248                 return NT_STATUS_INVALID_PARAMETER;
1249
1250         return gums_cs_set_nttime(com_set, GUMS_SET_LOGON_TIME, logon_time);
1251 }
1252
1253 NTSTATUS gums_cs_set_logoff_time(GUMS_COMMIT_SET *com_set, NTTIME *logoff_time)
1254 {
1255         if (com_set->type != GUMS_OBJ_NORMAL_USER)
1256                 return NT_STATUS_INVALID_PARAMETER;
1257
1258         return gums_cs_set_nttime(com_set, GUMS_SET_LOGOFF_TIME, logoff_time);
1259 }
1260
1261 NTSTATUS gums_cs_set_kickoff_time(GUMS_COMMIT_SET *com_set, NTTIME *kickoff_time)
1262 {
1263         if (com_set->type != GUMS_OBJ_NORMAL_USER)
1264                 return NT_STATUS_INVALID_PARAMETER;
1265
1266         return gums_cs_set_nttime(com_set, GUMS_SET_KICKOFF_TIME, kickoff_time);
1267 }
1268
1269 NTSTATUS gums_cs_set_pass_last_set_time(GUMS_COMMIT_SET *com_set, NTTIME *pls_time)
1270 {
1271         if (com_set->type != GUMS_OBJ_NORMAL_USER)
1272                 return NT_STATUS_INVALID_PARAMETER;
1273
1274         return gums_cs_set_nttime(com_set, GUMS_SET_LOGON_TIME, pls_time);
1275 }
1276
1277 NTSTATUS gums_cs_set_pass_can_change_time(GUMS_COMMIT_SET *com_set, NTTIME *pcc_time)
1278 {
1279         if (com_set->type != GUMS_OBJ_NORMAL_USER)
1280                 return NT_STATUS_INVALID_PARAMETER;
1281
1282         return gums_cs_set_nttime(com_set, GUMS_SET_LOGON_TIME, pcc_time);
1283 }
1284
1285 NTSTATUS gums_cs_set_pass_must_change_time(GUMS_COMMIT_SET *com_set, NTTIME *pmc_time)
1286 {
1287         if (com_set->type != GUMS_OBJ_NORMAL_USER)
1288                 return NT_STATUS_INVALID_PARAMETER;
1289
1290         return gums_cs_set_nttime(com_set, GUMS_SET_LOGON_TIME, pmc_time);
1291 }
1292
1293 NTSTATUS gums_cs_add_sids_to_group(GUMS_COMMIT_SET *com_set, const DOM_SID **sids, const uint32 count)
1294 {
1295         NTSTATUS ret;
1296         GUMS_DATA_SET *data_set;
1297         DOM_SID **new_sids;
1298         int i;
1299
1300         if (!com_set || !sids)
1301                 return NT_STATUS_INVALID_PARAMETER;
1302
1303         if (!NT_STATUS_IS_OK(ret = gums_cs_grow_data_set(com_set, 1)))
1304                 return ret;
1305
1306         data_set = &((com_set->data)[com_set->count - 1]);
1307         
1308         data_set->type = GUMS_ADD_SID_LIST;
1309         new_sids = (DOM_SID **)talloc(com_set->mem_ctx, (sizeof(void *) * count));
1310         if (new_sids == NULL)
1311                 return NT_STATUS_NO_MEMORY;
1312         for (i = 0; i < count; i++) {
1313                 new_sids[i] = sid_dup_talloc(com_set->mem_ctx, sids[i]);
1314                 if (new_sids[i] == NULL)
1315                         return NT_STATUS_NO_MEMORY;
1316         }
1317
1318         (SEC_DESC *)(data_set->data) = new_sids;
1319
1320         return NT_STATUS_OK;    
1321 }
1322
1323 NTSTATUS gums_cs_add_users_to_group(GUMS_COMMIT_SET *com_set, const DOM_SID **sids, const uint32 count)
1324 {
1325         if (!com_set || !sids)
1326                 return NT_STATUS_INVALID_PARAMETER;
1327         if (com_set->type != GUMS_OBJ_GROUP || com_set->type != GUMS_OBJ_ALIAS)
1328                 return NT_STATUS_INVALID_PARAMETER;
1329
1330         return gums_cs_add_sids_to_group(com_set, sids, count); 
1331 }
1332
1333 NTSTATUS gums_cs_add_groups_to_group(GUMS_COMMIT_SET *com_set, const DOM_SID **sids, const uint32 count)
1334 {
1335         if (!com_set || !sids)
1336                 return NT_STATUS_INVALID_PARAMETER;
1337         if (com_set->type != GUMS_OBJ_ALIAS)
1338                 return NT_STATUS_INVALID_PARAMETER;
1339
1340         return gums_cs_add_sids_to_group(com_set, sids, count); 
1341 }
1342
1343 NTSTATUS gums_cs_del_sids_from_group(GUMS_COMMIT_SET *com_set, const DOM_SID **sids, const uint32 count)
1344 {
1345         NTSTATUS ret;
1346         GUMS_DATA_SET *data_set;
1347         DOM_SID **new_sids;
1348         int i;
1349
1350         if (!com_set || !sids)
1351                 return NT_STATUS_INVALID_PARAMETER;
1352         if (com_set->type != GUMS_OBJ_GROUP || com_set->type != GUMS_OBJ_ALIAS)
1353                 return NT_STATUS_INVALID_PARAMETER;
1354
1355         if (!NT_STATUS_IS_OK(ret = gums_cs_grow_data_set(com_set, 1)))
1356                 return ret;
1357
1358         data_set = &((com_set->data)[com_set->count - 1]);
1359         
1360         data_set->type = GUMS_DEL_SID_LIST;
1361         new_sids = (DOM_SID **)talloc(com_set->mem_ctx, (sizeof(void *) * count));
1362         if (new_sids == NULL)
1363                 return NT_STATUS_NO_MEMORY;
1364         for (i = 0; i < count; i++) {
1365                 new_sids[i] = sid_dup_talloc(com_set->mem_ctx, sids[i]);
1366                 if (new_sids[i] == NULL)
1367                         return NT_STATUS_NO_MEMORY;
1368         }
1369
1370         (SEC_DESC *)(data_set->data) = new_sids;
1371
1372         return NT_STATUS_OK;    
1373 }
1374
1375 NTSTATUS gums_ds_set_sids_in_group(GUMS_COMMIT_SET *com_set, const DOM_SID **sids, const uint32 count)
1376 {
1377         NTSTATUS ret;
1378         GUMS_DATA_SET *data_set;
1379         DOM_SID **new_sids;
1380         int i;
1381
1382         if (!com_set || !sids)
1383                 return NT_STATUS_INVALID_PARAMETER;
1384         if (com_set->type != GUMS_OBJ_GROUP || com_set->type != GUMS_OBJ_ALIAS)
1385                 return NT_STATUS_INVALID_PARAMETER;
1386
1387         if (!NT_STATUS_IS_OK(ret = gums_cs_grow_data_set(com_set, 1)))
1388                 return ret;
1389
1390         data_set = &((com_set->data)[com_set->count - 1]);
1391         
1392         data_set->type = GUMS_SET_SID_LIST;
1393         new_sids = (DOM_SID **)talloc(com_set->mem_ctx, (sizeof(void *) * count));
1394         if (new_sids == NULL)
1395                 return NT_STATUS_NO_MEMORY;
1396         for (i = 0; i < count; i++) {
1397                 new_sids[i] = sid_dup_talloc(com_set->mem_ctx, sids[i]);
1398                 if (new_sids[i] == NULL)
1399                         return NT_STATUS_NO_MEMORY;
1400         }
1401
1402         (SEC_DESC *)(data_set->data) = new_sids;
1403
1404         return NT_STATUS_OK;    
1405 }
1406
1407 NTSTATUS gums_commit_data(GUMS_COMMIT_SET *set)
1408 {
1409         NTSTATUS ret;
1410         GUMS_FUNCTIONS *fns;
1411
1412         if (!NT_STATUS_IS_OK(ret = get_gums_fns(&fns))) {
1413                 DEBUG(0, ("gums_commit_data: unable to get gums functions! backend uninitialized?\n"));
1414                 return ret;
1415         }
1416         return fns->set_object_values(&(set->sid), set->count, set->data);
1417 }
1418
1419 NTSTATUS gums_destroy_commit_set(GUMS_COMMIT_SET **com_set)
1420 {
1421         talloc_destroy((*com_set)->mem_ctx);
1422         *com_set = NULL;
1423
1424         return NT_STATUS_OK;
1425 }
1426