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