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