objectclass -> objectClass
[ira/wip.git] / source3 / utils / net_sam.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  Local SAM access routines
4  *  Copyright (C) Volker Lendecke 2006
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20
21 #include "includes.h"
22 #include "utils/net.h"
23
24 /*
25  * Set a user's data
26  */
27
28 static int net_sam_userset(int argc, const char **argv, const char *field,
29                            bool (*fn)(struct samu *, const char *,
30                                       enum pdb_value_state))
31 {
32         struct samu *sam_acct = NULL;
33         DOM_SID sid;
34         enum lsa_SidType type;
35         const char *dom, *name;
36         NTSTATUS status;
37
38         if (argc != 2) {
39                 d_fprintf(stderr, "usage: net sam set %s <user> <value>\n",
40                           field);
41                 return -1;
42         }
43
44         if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
45                          &dom, &name, &sid, &type)) {
46                 d_fprintf(stderr, "Could not find name %s\n", argv[0]);
47                 return -1;
48         }
49
50         if (type != SID_NAME_USER) {
51                 d_fprintf(stderr, "%s is a %s, not a user\n", argv[0],
52                           sid_type_lookup(type));
53                 return -1;
54         }
55
56         if ( !(sam_acct = samu_new( NULL )) ) {
57                 d_fprintf(stderr, "Internal error\n");
58                 return -1;
59         }
60
61         if (!pdb_getsampwsid(sam_acct, &sid)) {
62                 d_fprintf(stderr, "Loading user %s failed\n", argv[0]);
63                 return -1;
64         }
65
66         if (!fn(sam_acct, argv[1], PDB_CHANGED)) {
67                 d_fprintf(stderr, "Internal error\n");
68                 return -1;
69         }
70
71         status = pdb_update_sam_account(sam_acct);
72         if (!NT_STATUS_IS_OK(status)) {
73                 d_fprintf(stderr, "Updating sam account %s failed with %s\n",
74                           argv[0], nt_errstr(status));
75                 return -1;
76         }
77
78         TALLOC_FREE(sam_acct);
79
80         d_printf("Updated %s for %s\\%s to %s\n", field, dom, name, argv[1]);
81         return 0;
82 }
83
84 static int net_sam_set_fullname(int argc, const char **argv)
85 {
86         return net_sam_userset(argc, argv, "fullname",
87                                pdb_set_fullname);
88 }
89
90 static int net_sam_set_logonscript(int argc, const char **argv)
91 {
92         return net_sam_userset(argc, argv, "logonscript",
93                                pdb_set_logon_script);
94 }
95
96 static int net_sam_set_profilepath(int argc, const char **argv)
97 {
98         return net_sam_userset(argc, argv, "profilepath",
99                                pdb_set_profile_path);
100 }
101
102 static int net_sam_set_homedrive(int argc, const char **argv)
103 {
104         return net_sam_userset(argc, argv, "homedrive",
105                                pdb_set_dir_drive);
106 }
107
108 static int net_sam_set_homedir(int argc, const char **argv)
109 {
110         return net_sam_userset(argc, argv, "homedir",
111                                pdb_set_homedir);
112 }
113
114 static int net_sam_set_workstations(int argc, const char **argv)
115 {
116         return net_sam_userset(argc, argv, "workstations",
117                                pdb_set_workstations);
118 }
119
120 /*
121  * Set account flags
122  */
123
124 static int net_sam_set_userflag(int argc, const char **argv, const char *field,
125                                 uint16 flag)
126 {
127         struct samu *sam_acct = NULL;
128         DOM_SID sid;
129         enum lsa_SidType type;
130         const char *dom, *name;
131         NTSTATUS status;
132         uint16 acct_flags;
133
134         if ((argc != 2) || (!strequal(argv[1], "yes") &&
135                             !strequal(argv[1], "no"))) {
136                 d_fprintf(stderr, "usage: net sam set %s <user> [yes|no]\n",
137                           field);
138                 return -1;
139         }
140
141         if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
142                          &dom, &name, &sid, &type)) {
143                 d_fprintf(stderr, "Could not find name %s\n", argv[0]);
144                 return -1;
145         }
146
147         if (type != SID_NAME_USER) {
148                 d_fprintf(stderr, "%s is a %s, not a user\n", argv[0],
149                           sid_type_lookup(type));
150                 return -1;
151         }
152
153         if ( !(sam_acct = samu_new( NULL )) ) {
154                 d_fprintf(stderr, "Internal error\n");
155                 return -1;
156         }
157
158         if (!pdb_getsampwsid(sam_acct, &sid)) {
159                 d_fprintf(stderr, "Loading user %s failed\n", argv[0]);
160                 return -1;
161         }
162
163         acct_flags = pdb_get_acct_ctrl(sam_acct);
164
165         if (strequal(argv[1], "yes")) {
166                 acct_flags |= flag;
167         } else {
168                 acct_flags &= ~flag;
169         }
170
171         pdb_set_acct_ctrl(sam_acct, acct_flags, PDB_CHANGED);
172
173         status = pdb_update_sam_account(sam_acct);
174         if (!NT_STATUS_IS_OK(status)) {
175                 d_fprintf(stderr, "Updating sam account %s failed with %s\n",
176                           argv[0], nt_errstr(status));
177                 return -1;
178         }
179
180         TALLOC_FREE(sam_acct);
181
182         d_fprintf(stderr, "Updated flag %s for %s\\%s to %s\n", field, dom,
183                   name, argv[1]);
184         return 0;
185 }
186
187 static int net_sam_set_disabled(int argc, const char **argv)
188 {
189         return net_sam_set_userflag(argc, argv, "disabled", ACB_DISABLED);
190 }
191
192 static int net_sam_set_pwnotreq(int argc, const char **argv)
193 {
194         return net_sam_set_userflag(argc, argv, "pwnotreq", ACB_PWNOTREQ);
195 }
196
197 static int net_sam_set_autolock(int argc, const char **argv)
198 {
199         return net_sam_set_userflag(argc, argv, "autolock", ACB_AUTOLOCK);
200 }
201
202 static int net_sam_set_pwnoexp(int argc, const char **argv)
203 {
204         return net_sam_set_userflag(argc, argv, "pwnoexp", ACB_PWNOEXP);
205 }
206
207 /*
208  * Set pass last change time, based on force pass change now
209  */
210
211 static int net_sam_set_pwdmustchangenow(int argc, const char **argv)
212 {
213         struct samu *sam_acct = NULL;
214         DOM_SID sid;
215         enum lsa_SidType type;
216         const char *dom, *name;
217         NTSTATUS status;
218
219         if ((argc != 2) || (!strequal(argv[1], "yes") &&
220                             !strequal(argv[1], "no"))) {
221                 d_fprintf(stderr, "usage: net sam set pwdmustchangenow <user> [yes|no]\n");
222                 return -1;
223         }
224
225         if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
226                          &dom, &name, &sid, &type)) {
227                 d_fprintf(stderr, "Could not find name %s\n", argv[0]);
228                 return -1;
229         }
230
231         if (type != SID_NAME_USER) {
232                 d_fprintf(stderr, "%s is a %s, not a user\n", argv[0],
233                           sid_type_lookup(type));
234                 return -1;
235         }
236
237         if ( !(sam_acct = samu_new( NULL )) ) {
238                 d_fprintf(stderr, "Internal error\n");
239                 return -1;
240         }
241
242         if (!pdb_getsampwsid(sam_acct, &sid)) {
243                 d_fprintf(stderr, "Loading user %s failed\n", argv[0]);
244                 return -1;
245         }
246
247         if (strequal(argv[1], "yes")) {
248                 pdb_set_pass_last_set_time(sam_acct, 0, PDB_CHANGED);
249         } else {
250                 pdb_set_pass_last_set_time(sam_acct, time(NULL), PDB_CHANGED);
251         }
252
253         status = pdb_update_sam_account(sam_acct);
254         if (!NT_STATUS_IS_OK(status)) {
255                 d_fprintf(stderr, "Updating sam account %s failed with %s\n",
256                           argv[0], nt_errstr(status));
257                 return -1;
258         }
259
260         TALLOC_FREE(sam_acct);
261
262         d_fprintf(stderr, "Updated 'user must change password at next logon' for %s\\%s to %s\n", dom,
263                   name, argv[1]);
264         return 0;
265 }
266
267
268 /*
269  * Set a user's or a group's comment
270  */
271
272 static int net_sam_set_comment(int argc, const char **argv)
273 {
274         GROUP_MAP map;
275         DOM_SID sid;
276         enum lsa_SidType type;
277         const char *dom, *name;
278         NTSTATUS status;
279
280         if (argc != 2) {
281                 d_fprintf(stderr, "usage: net sam set comment <name> "
282                           "<comment>\n");
283                 return -1;
284         }
285
286         if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
287                          &dom, &name, &sid, &type)) {
288                 d_fprintf(stderr, "Could not find name %s\n", argv[0]);
289                 return -1;
290         }
291
292         if (type == SID_NAME_USER) {
293                 return net_sam_userset(argc, argv, "comment",
294                                        pdb_set_acct_desc);
295         }
296
297         if ((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) &&
298             (type != SID_NAME_WKN_GRP)) {
299                 d_fprintf(stderr, "%s is a %s, not a group\n", argv[0],
300                           sid_type_lookup(type));
301                 return -1;
302         }
303
304         if (!pdb_getgrsid(&map, sid)) {
305                 d_fprintf(stderr, "Could not load group %s\n", argv[0]);
306                 return -1;
307         }
308
309         fstrcpy(map.comment, argv[1]);
310
311         status = pdb_update_group_mapping_entry(&map);
312
313         if (!NT_STATUS_IS_OK(status)) {
314                 d_fprintf(stderr, "Updating group mapping entry failed with "
315                           "%s\n", nt_errstr(status));
316                 return -1;
317         }
318
319         d_printf("Updated comment of group %s\\%s to %s\n", dom, name,
320                  argv[1]);
321
322         return 0;
323 }
324
325 static int net_sam_set(int argc, const char **argv)
326 {
327         struct functable2 func[] = {
328                 { "homedir", net_sam_set_homedir,
329                   "Change a user's home directory" },
330                 { "profilepath", net_sam_set_profilepath,
331                   "Change a user's profile path" },
332                 { "comment", net_sam_set_comment,
333                   "Change a users or groups description" },
334                 { "fullname", net_sam_set_fullname,
335                   "Change a user's full name" },
336                 { "logonscript", net_sam_set_logonscript,
337                   "Change a user's logon script" },
338                 { "homedrive", net_sam_set_homedrive,
339                   "Change a user's home drive" },
340                 { "workstations", net_sam_set_workstations,
341                   "Change a user's allowed workstations" },
342                 { "disabled", net_sam_set_disabled,
343                   "Disable/Enable a user" },
344                 { "pwnotreq", net_sam_set_pwnotreq,
345                   "Disable/Enable the password not required flag" },
346                 { "autolock", net_sam_set_autolock,
347                   "Disable/Enable a user's lockout flag" },
348                 { "pwnoexp", net_sam_set_pwnoexp,
349                   "Disable/Enable whether a user's pw does not expire" },
350                 { "pwdmustchangenow", net_sam_set_pwdmustchangenow,
351                   "Force users password must change at next logon" },
352                 {NULL, NULL}
353         };
354
355         return net_run_function2(argc, argv, "net sam set", func);
356 }
357
358 /*
359  * Manage account policies
360  */
361
362 static int net_sam_policy_set(int argc, const char **argv)
363 {
364         const char *account_policy = NULL;
365         uint32 value = 0;
366         uint32 old_value = 0;
367         int field;
368         char *endptr;
369
370         if (argc != 2) {
371                 d_fprintf(stderr, "usage: net sam policy set " 
372                           "\"<account policy>\" <value> \n");
373                 return -1;
374         }
375
376         account_policy = argv[0];
377         field = account_policy_name_to_fieldnum(account_policy);
378
379         if (strequal(argv[1], "forever") || strequal(argv[1], "never")
380             || strequal(argv[1], "off")) {
381                 value = -1;
382         }
383         else {
384                 value = strtoul(argv[1], &endptr, 10);
385
386                 if ((endptr == argv[1]) || (endptr[0] != '\0')) {
387                         d_printf("Unable to set policy \"%s\"! Invalid value "
388                                  "\"%s\".\n", 
389                                  account_policy, argv[1]); 
390                         return -1;
391                 }
392         }
393
394         if (field == 0) {
395                 const char **names;
396                 int i, count;
397
398                 account_policy_names_list(&names, &count);
399                 d_fprintf(stderr, "No account policy \"%s\"!\n\n", argv[0]);
400                 d_fprintf(stderr, "Valid account policies are:\n");
401
402                 for (i=0; i<count; i++) {
403                         d_fprintf(stderr, "%s\n", names[i]);
404                 }
405
406                 SAFE_FREE(names);
407                 return -1;
408         }
409
410         if (!pdb_get_account_policy(field, &old_value)) {
411                 d_fprintf(stderr, "Valid account policy, but unable to fetch "
412                           "value!\n");
413         } else {
414                 d_printf("Account policy \"%s\" value was: %d\n", account_policy,
415                         old_value);
416         }
417
418         if (!pdb_set_account_policy(field, value)) {
419                 d_fprintf(stderr, "Valid account policy, but unable to "
420                           "set value!\n");
421                 return -1;
422         } else {
423                 d_printf("Account policy \"%s\" value is now: %d\n", account_policy,
424                         value);
425         }
426
427         return 0;
428 }
429
430 static int net_sam_policy_show(int argc, const char **argv)
431 {
432         const char *account_policy = NULL;
433         uint32 old_value;
434         int field;
435
436         if (argc != 1) {
437                 d_fprintf(stderr, "usage: net sam policy show"
438                           " \"<account policy>\" \n");
439                 return -1;
440         }
441         
442         account_policy = argv[0];
443         field = account_policy_name_to_fieldnum(account_policy);
444
445         if (field == 0) {
446                 const char **names;
447                 int count;
448                 int i;
449                 account_policy_names_list(&names, &count);
450                 d_fprintf(stderr, "No account policy by that name!\n");
451                 if (count != 0) {
452                         d_fprintf(stderr, "Valid account policies "
453                                   "are:\n");
454                         for (i=0; i<count; i++) {
455                                 d_fprintf(stderr, "%s\n", names[i]);
456                         }
457                 }
458                 SAFE_FREE(names);
459                 return -1;
460         }
461
462         if (!pdb_get_account_policy(field, &old_value)) {
463                 fprintf(stderr, "Valid account policy, but unable to "
464                         "fetch value!\n");
465                 return -1;
466         }
467         
468         printf("Account policy \"%s\" description: %s\n",
469                account_policy, account_policy_get_desc(field));
470         printf("Account policy \"%s\" value is: %d\n", account_policy,
471                old_value);
472         return 0;
473 }
474
475 static int net_sam_policy_list(int argc, const char **argv)
476 {
477         const char **names;
478         int count;
479         int i;
480         account_policy_names_list(&names, &count);
481         if (count != 0) {
482                 d_fprintf(stderr, "Valid account policies "
483                           "are:\n");
484                 for (i = 0; i < count ; i++) {
485                         d_fprintf(stderr, "%s\n", names[i]);
486                 }
487         }
488         SAFE_FREE(names);
489         return -1;
490 }
491
492 static int net_sam_policy(int argc, const char **argv)
493 {
494         struct functable2 func[] = {
495                 { "list", net_sam_policy_list,
496                   "List account policies" },
497                 { "show", net_sam_policy_show,
498                   "Show account policies" },
499                 { "set", net_sam_policy_set,
500                   "Change account policies" },
501                 {NULL, NULL}
502         };
503
504         return net_run_function2(argc, argv, "net sam policy", func);
505 }
506
507 extern PRIVS privs[];
508
509 static int net_sam_rights_list(int argc, const char **argv)
510 {
511         SE_PRIV mask;
512
513         if (argc > 1) {
514                 d_fprintf(stderr, "usage: net sam rights list [privilege name]\n");
515                 return -1;
516         }
517
518         if (argc == 0) {
519                 int i;
520                 int num = count_all_privileges();
521
522                 for (i=0; i<num; i++) {
523                         d_printf("%s\n", privs[i].name);
524                 }
525                 return 0;
526         }
527
528         if (se_priv_from_name(argv[0], &mask)) {
529                 DOM_SID *sids;
530                 int i, num_sids;
531                 NTSTATUS status;
532
533                 status = privilege_enum_sids(&mask, talloc_tos(),
534                                              &sids, &num_sids);
535                 if (!NT_STATUS_IS_OK(status)) {
536                         d_fprintf(stderr, "Could not list rights: %s\n",
537                                   nt_errstr(status));
538                         return -1;
539                 }
540
541                 for (i=0; i<num_sids; i++) {
542                         const char *dom, *name;
543                         enum lsa_SidType type;
544
545                         if (lookup_sid(talloc_tos(), &sids[i], &dom, &name,
546                                        &type)) {
547                                 d_printf("%s\\%s\n", dom, name);
548                         }
549                         else {
550                                 d_printf("%s\n", sid_string_tos(&sids[i]));
551                         }
552                 }
553                 return 0;
554         }
555
556         return -1;
557 }
558
559 static int net_sam_rights_grant(int argc, const char **argv)
560 {
561         DOM_SID sid;
562         enum lsa_SidType type;
563         const char *dom, *name;
564         SE_PRIV mask;
565
566         if (argc != 2) {
567                 d_fprintf(stderr, "usage: net sam rights grant <name> "
568                           "<right>\n");
569                 return -1;
570         }
571
572         if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
573                          &dom, &name, &sid, &type)) {
574                 d_fprintf(stderr, "Could not find name %s\n", argv[0]);
575                 return -1;
576         }
577
578         if (!se_priv_from_name(argv[1], &mask)) {
579                 d_fprintf(stderr, "%s unknown\n", argv[1]);
580                 return -1;
581         }
582
583         if (!grant_privilege(&sid, &mask)) {
584                 d_fprintf(stderr, "Could not grant privilege\n");
585                 return -1;
586         }
587
588         d_printf("Granted %s to %s\\%s\n", argv[1], dom, name);
589         return 0;
590 }
591
592 static int net_sam_rights_revoke(int argc, const char **argv)
593 {
594         DOM_SID sid;
595         enum lsa_SidType type;
596         const char *dom, *name;
597         SE_PRIV mask;
598
599         if (argc != 2) {
600                 d_fprintf(stderr, "usage: net sam rights revoke <name> "
601                           "<right>\n");
602                 return -1;
603         }
604
605         if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
606                          &dom, &name, &sid, &type)) {
607                 d_fprintf(stderr, "Could not find name %s\n", argv[0]);
608                 return -1;
609         }
610
611         if (!se_priv_from_name(argv[1], &mask)) {
612                 d_fprintf(stderr, "%s unknown\n", argv[1]);
613                 return -1;
614         }
615
616         if (!revoke_privilege(&sid, &mask)) {
617                 d_fprintf(stderr, "Could not revoke privilege\n");
618                 return -1;
619         }
620
621         d_printf("Revoked %s from %s\\%s\n", argv[1], dom, name);
622         return 0;
623 }
624
625 static int net_sam_rights(int argc, const char **argv)
626 {
627         struct functable2 func[] = {
628                 { "list", net_sam_rights_list,
629                   "List possible user rights" },
630                 { "grant", net_sam_rights_grant,
631                   "Grant a right" },
632                 { "revoke", net_sam_rights_revoke,
633                   "Revoke a right" },
634                 { NULL }
635         };
636         return net_run_function2(argc, argv, "net sam rights", func);
637 }
638
639 /*
640  * Map a unix group to a domain group
641  */
642
643 static NTSTATUS map_unix_group(const struct group *grp, GROUP_MAP *pmap)
644 {
645         NTSTATUS status;
646         GROUP_MAP map;
647         const char *grpname, *dom, *name;
648         uint32 rid;
649
650         if (pdb_getgrgid(&map, grp->gr_gid)) {
651                 return NT_STATUS_GROUP_EXISTS;
652         }
653
654         map.gid = grp->gr_gid;
655         grpname = grp->gr_name;
656
657         if (lookup_name(talloc_tos(), grpname, LOOKUP_NAME_LOCAL,
658                         &dom, &name, NULL, NULL)) {
659
660                 const char *tmp = talloc_asprintf(
661                         talloc_tos(), "Unix Group %s", grp->gr_name);
662
663                 DEBUG(5, ("%s exists as %s\\%s, retrying as \"%s\"\n",
664                           grpname, dom, name, tmp));
665                 grpname = tmp;
666         }
667
668         if (lookup_name(talloc_tos(), grpname, LOOKUP_NAME_LOCAL,
669                         NULL, NULL, NULL, NULL)) {
670                 DEBUG(3, ("\"%s\" exists, can't map it\n", grp->gr_name));
671                 return NT_STATUS_GROUP_EXISTS;
672         }
673
674         fstrcpy(map.nt_name, grpname);
675
676         if (pdb_rid_algorithm()) {
677                 rid = algorithmic_pdb_gid_to_group_rid( grp->gr_gid );
678         } else {
679                 if (!pdb_new_rid(&rid)) {
680                         DEBUG(3, ("Could not get a new RID for %s\n",
681                                   grp->gr_name));
682                         return NT_STATUS_ACCESS_DENIED;
683                 }
684         }
685
686         sid_compose(&map.sid, get_global_sam_sid(), rid);
687         map.sid_name_use = SID_NAME_DOM_GRP;
688         fstrcpy(map.comment, talloc_asprintf(talloc_tos(), "Unix Group %s",
689                                              grp->gr_name));
690
691         status = pdb_add_group_mapping_entry(&map);
692         if (NT_STATUS_IS_OK(status)) {
693                 *pmap = map;
694         }
695         return status;
696 }
697
698 static int net_sam_mapunixgroup(int argc, const char **argv)
699 {
700         NTSTATUS status;
701         GROUP_MAP map;
702         struct group *grp;
703
704         if (argc != 1) {
705                 d_fprintf(stderr, "usage: net sam mapunixgroup <name>\n");
706                 return -1;
707         }
708
709         grp = getgrnam(argv[0]);
710         if (grp == NULL) {
711                 d_fprintf(stderr, "Could not find group %s\n", argv[0]);
712                 return -1;
713         }
714
715         status = map_unix_group(grp, &map);
716
717         if (!NT_STATUS_IS_OK(status)) {
718                 d_fprintf(stderr, "Mapping group %s failed with %s\n",
719                           argv[0], nt_errstr(status));
720                 return -1;
721         }
722
723         d_printf("Mapped unix group %s to SID %s\n", argv[0],
724                  sid_string_tos(&map.sid));
725
726         return 0;
727 }
728
729 /*
730  * Remove a group mapping
731  */
732
733 static NTSTATUS unmap_unix_group(const struct group *grp, GROUP_MAP *pmap)
734 {
735         NTSTATUS status;
736         GROUP_MAP map;
737         const char *grpname;
738         DOM_SID dom_sid;
739
740         map.gid = grp->gr_gid;
741         grpname = grp->gr_name;
742
743         if (!lookup_name(talloc_tos(), grpname, LOOKUP_NAME_LOCAL,
744                         NULL, NULL, NULL, NULL)) {
745                 DEBUG(3, ("\"%s\" does not exist, can't unmap it\n", grp->gr_name));
746                 return NT_STATUS_NO_SUCH_GROUP;
747         }
748
749         fstrcpy(map.nt_name, grpname);
750
751         if (!pdb_gid_to_sid(map.gid, &dom_sid)) {
752                 return NT_STATUS_UNSUCCESSFUL;
753         }
754
755         status = pdb_delete_group_mapping_entry(dom_sid);
756
757         return status;
758 }
759
760 static int net_sam_unmapunixgroup(int argc, const char **argv)
761 {
762         NTSTATUS status;
763         GROUP_MAP map;
764         struct group *grp;
765
766         if (argc != 1) {
767                 d_fprintf(stderr, "usage: net sam unmapunixgroup <name>\n");
768                 return -1;
769         }
770
771         grp = getgrnam(argv[0]);
772         if (grp == NULL) {
773                 d_fprintf(stderr, "Could not find mapping for group %s.\n", argv[0]);
774                 return -1;
775         }
776
777         status = unmap_unix_group(grp, &map);
778
779         if (!NT_STATUS_IS_OK(status)) {
780                 d_fprintf(stderr, "Unmapping group %s failed with %s.\n",
781                           argv[0], nt_errstr(status));
782                 return -1;
783         }
784
785         d_printf("Unmapped unix group %s.\n", argv[0]);
786
787         return 0;
788 }
789
790 /*
791  * Create a local group
792  */
793
794 static int net_sam_createlocalgroup(int argc, const char **argv)
795 {
796         NTSTATUS status;
797         uint32 rid;
798
799         if (argc != 1) {
800                 d_fprintf(stderr, "usage: net sam createlocalgroup <name>\n");
801                 return -1;
802         }
803
804         if (!winbind_ping()) {
805                 d_fprintf(stderr, "winbind seems not to run. createlocalgroup "
806                           "only works when winbind runs.\n");
807                 return -1;
808         }
809
810         status = pdb_create_alias(argv[0], &rid);
811
812         if (!NT_STATUS_IS_OK(status)) {
813                 d_fprintf(stderr, "Creating %s failed with %s\n",
814                           argv[0], nt_errstr(status));
815                 return -1;
816         }
817
818         d_printf("Created local group %s with RID %d\n", argv[0], rid);
819
820         return 0;
821 }
822
823 /*
824  * Delete a local group
825  */
826
827 static int net_sam_deletelocalgroup(int argc, const char **argv)
828 {
829         DOM_SID sid;
830         enum lsa_SidType type;
831         const char *dom, *name;
832         NTSTATUS status;
833
834         if (argc != 1) {
835                 d_fprintf(stderr, "usage: net sam deletelocalgroup <name>\n");
836                 return -1;
837         }
838
839         if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
840                          &dom, &name, &sid, &type)) {
841                 d_fprintf(stderr, "Could not find %s.\n", argv[0]);
842                 return -1;
843         }
844
845         if (type != SID_NAME_ALIAS) {
846                 d_fprintf(stderr, "%s is a %s, not a local group.\n", argv[0],
847                           sid_type_lookup(type));
848                 return -1;
849         }
850
851         status = pdb_delete_alias(&sid);
852
853         if (!NT_STATUS_IS_OK(status)) {
854                 d_fprintf(stderr, "Deleting local group %s failed with %s\n",
855                           argv[0], nt_errstr(status));
856                 return -1;
857         }
858
859         d_printf("Deleted local group %s.\n", argv[0]);
860
861         return 0;
862 }
863
864 /*
865  * Create a local group
866  */
867
868 static int net_sam_createbuiltingroup(int argc, const char **argv)
869 {
870         NTSTATUS status;
871         uint32 rid;
872         enum lsa_SidType type;
873         fstring groupname;
874         DOM_SID sid;
875
876         if (argc != 1) {
877                 d_fprintf(stderr, "usage: net sam createbuiltingroup <name>\n");
878                 return -1;
879         }
880
881         if (!winbind_ping()) {
882                 d_fprintf(stderr, "winbind seems not to run. createlocalgroup "
883                           "only works when winbind runs.\n");
884                 return -1;
885         }
886
887         /* validate the name and get the group */
888         
889         fstrcpy( groupname, "BUILTIN\\" );
890         fstrcat( groupname, argv[0] );
891         
892         if ( !lookup_name(talloc_tos(), groupname, LOOKUP_NAME_ALL, NULL,
893                           NULL, &sid, &type)) {
894                 d_fprintf(stderr, "%s is not a BUILTIN group\n", argv[0]);
895                 return -1;
896         }
897         
898         if ( !sid_peek_rid( &sid, &rid ) ) {
899                 d_fprintf(stderr, "Failed to get RID for %s\n", argv[0]);
900                 return -1;
901         }
902
903         status = pdb_create_builtin_alias( rid );
904
905         if (!NT_STATUS_IS_OK(status)) {
906                 d_fprintf(stderr, "Creating %s failed with %s\n",
907                           argv[0], nt_errstr(status));
908                 return -1;
909         }
910
911         d_printf("Created BUILTIN group %s with RID %d\n", argv[0], rid);
912
913         return 0;
914 }
915
916 /*
917  * Add a group member
918  */
919
920 static int net_sam_addmem(int argc, const char **argv)
921 {
922         const char *groupdomain, *groupname, *memberdomain, *membername;
923         DOM_SID group, member;
924         enum lsa_SidType grouptype, membertype;
925         NTSTATUS status;
926
927         if (argc != 2) {
928                 d_fprintf(stderr, "usage: net sam addmem <group> <member>\n");
929                 return -1;
930         }
931
932         if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
933                          &groupdomain, &groupname, &group, &grouptype)) {
934                 d_fprintf(stderr, "Could not find group %s\n", argv[0]);
935                 return -1;
936         }
937
938         /* check to see if the member to be added is a name or a SID */
939
940         if (!lookup_name(talloc_tos(), argv[1], LOOKUP_NAME_LOCAL,
941                          &memberdomain, &membername, &member, &membertype))
942         {
943                 /* try it as a SID */
944
945                 if ( !string_to_sid( &member, argv[1] ) ) {
946                         d_fprintf(stderr, "Could not find member %s\n", argv[1]);
947                         return -1;
948                 }
949
950                 if ( !lookup_sid(talloc_tos(), &member, &memberdomain,
951                         &membername, &membertype) ) 
952                 {
953                         d_fprintf(stderr, "Could not resolve SID %s\n", argv[1]);
954                         return -1;
955                 }
956         }
957
958         if ((grouptype == SID_NAME_ALIAS) || (grouptype == SID_NAME_WKN_GRP)) {
959                 if ((membertype != SID_NAME_USER) &&
960                     (membertype != SID_NAME_DOM_GRP)) {
961                         d_fprintf(stderr, "%s is a local group, only users "
962                                   "and domain groups can be added.\n"
963                                   "%s is a %s\n", argv[0], argv[1],
964                                   sid_type_lookup(membertype));
965                         return -1;
966                 }
967                 status = pdb_add_aliasmem(&group, &member);
968
969                 if (!NT_STATUS_IS_OK(status)) {
970                         d_fprintf(stderr, "Adding local group member failed "
971                                   "with %s\n", nt_errstr(status));
972                         return -1;
973                 }
974         } else {
975                 d_fprintf(stderr, "Can only add members to local groups so "
976                           "far, %s is a %s\n", argv[0],
977                           sid_type_lookup(grouptype));
978                 return -1;
979         }
980
981         d_printf("Added %s\\%s to %s\\%s\n", memberdomain, membername, 
982                 groupdomain, groupname);
983
984         return 0;
985 }
986
987 /*
988  * Delete a group member
989  */
990
991 static int net_sam_delmem(int argc, const char **argv)
992 {
993         const char *groupdomain, *groupname;
994         const char *memberdomain = NULL;
995         const char *membername = NULL;
996         DOM_SID group, member;
997         enum lsa_SidType grouptype;
998         NTSTATUS status;
999
1000         if (argc != 2) {
1001                 d_fprintf(stderr, "usage: net sam delmem <group> <member>\n");
1002                 return -1;
1003         }
1004
1005         if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
1006                          &groupdomain, &groupname, &group, &grouptype)) {
1007                 d_fprintf(stderr, "Could not find group %s\n", argv[0]);
1008                 return -1;
1009         }
1010
1011         if (!lookup_name(talloc_tos(), argv[1], LOOKUP_NAME_LOCAL,
1012                          &memberdomain, &membername, &member, NULL)) {
1013                 if (!string_to_sid(&member, argv[1])) {
1014                         d_fprintf(stderr, "Could not find member %s\n",
1015                                   argv[1]);
1016                         return -1;
1017                 }
1018         }
1019
1020         if ((grouptype == SID_NAME_ALIAS) ||
1021             (grouptype == SID_NAME_WKN_GRP)) {
1022                 status = pdb_del_aliasmem(&group, &member);
1023
1024                 if (!NT_STATUS_IS_OK(status)) {
1025                         d_fprintf(stderr, "Deleting local group member failed "
1026                                   "with %s\n", nt_errstr(status));
1027                         return -1;
1028                 }
1029         } else {
1030                 d_fprintf(stderr, "Can only delete members from local groups "
1031                           "so far, %s is a %s\n", argv[0],
1032                           sid_type_lookup(grouptype));
1033                 return -1;
1034         }
1035
1036         if (membername != NULL) {
1037                 d_printf("Deleted %s\\%s from %s\\%s\n",
1038                          memberdomain, membername, groupdomain, groupname);
1039         } else {
1040                 d_printf("Deleted %s from %s\\%s\n",
1041                          sid_string_tos(&member), groupdomain, groupname);
1042         }
1043
1044         return 0;
1045 }
1046
1047 /*
1048  * List group members
1049  */
1050
1051 static int net_sam_listmem(int argc, const char **argv)
1052 {
1053         const char *groupdomain, *groupname;
1054         DOM_SID group;
1055         enum lsa_SidType grouptype;
1056         NTSTATUS status;
1057
1058         if (argc != 1) {
1059                 d_fprintf(stderr, "usage: net sam listmem <group>\n");
1060                 return -1;
1061         }
1062
1063         if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
1064                          &groupdomain, &groupname, &group, &grouptype)) {
1065                 d_fprintf(stderr, "Could not find group %s\n", argv[0]);
1066                 return -1;
1067         }
1068
1069         if ((grouptype == SID_NAME_ALIAS) ||
1070             (grouptype == SID_NAME_WKN_GRP)) {
1071                 DOM_SID *members = NULL;
1072                 size_t i, num_members = 0;
1073                 
1074                 status = pdb_enum_aliasmem(&group, &members, &num_members);
1075
1076                 if (!NT_STATUS_IS_OK(status)) {
1077                         d_fprintf(stderr, "Listing group members failed with "
1078                                   "%s\n", nt_errstr(status));
1079                         return -1;
1080                 }
1081
1082                 d_printf("%s\\%s has %u members\n", groupdomain, groupname,
1083                          (unsigned int)num_members);
1084                 for (i=0; i<num_members; i++) {
1085                         const char *dom, *name;
1086                         if (lookup_sid(talloc_tos(), &members[i],
1087                                        &dom, &name, NULL)) {
1088                                 d_printf(" %s\\%s\n", dom, name);
1089                         } else {
1090                                 d_printf(" %s\n", sid_string_tos(&members[i]));
1091                         }
1092                 }
1093
1094                 TALLOC_FREE(members);
1095         } else {
1096                 d_fprintf(stderr, "Can only list local group members so far.\n"
1097                           "%s is a %s\n", argv[0], sid_type_lookup(grouptype));
1098                 return -1;
1099         }
1100
1101         return 0;
1102 }
1103
1104 /*
1105  * Do the listing
1106  */
1107 static int net_sam_do_list(int argc, const char **argv,
1108                            struct pdb_search *search, const char *what)
1109 {
1110         bool verbose = (argc == 1);
1111
1112         if ((argc > 1) ||
1113             ((argc == 1) && !strequal(argv[0], "verbose"))) {
1114                 d_fprintf(stderr, "usage: net sam list %s [verbose]\n", what);
1115                 return -1;
1116         }
1117
1118         if (search == NULL) {
1119                 d_fprintf(stderr, "Could not start search\n");
1120                 return -1;
1121         }
1122
1123         while (True) {
1124                 struct samr_displayentry entry;
1125                 if (!search->next_entry(search, &entry)) {
1126                         break;
1127                 }
1128                 if (verbose) {
1129                         d_printf("%s:%d:%s\n",
1130                                  entry.account_name,
1131                                  entry.rid,
1132                                  entry.description);
1133                 } else {
1134                         d_printf("%s\n", entry.account_name);
1135                 }
1136         }
1137
1138         pdb_search_destroy(search);
1139         return 0;
1140 }
1141
1142 static int net_sam_list_users(int argc, const char **argv)
1143 {
1144         return net_sam_do_list(argc, argv, pdb_search_users(ACB_NORMAL),
1145                                "users");
1146 }
1147
1148 static int net_sam_list_groups(int argc, const char **argv)
1149 {
1150         return net_sam_do_list(argc, argv, pdb_search_groups(), "groups");
1151 }
1152
1153 static int net_sam_list_localgroups(int argc, const char **argv)
1154 {
1155         return net_sam_do_list(argc, argv,
1156                                pdb_search_aliases(get_global_sam_sid()),
1157                                "localgroups");
1158 }
1159
1160 static int net_sam_list_builtin(int argc, const char **argv)
1161 {
1162         return net_sam_do_list(argc, argv,
1163                                pdb_search_aliases(&global_sid_Builtin),
1164                                "builtin");
1165 }
1166
1167 static int net_sam_list_workstations(int argc, const char **argv)
1168 {
1169         return net_sam_do_list(argc, argv,
1170                                pdb_search_users(ACB_WSTRUST),
1171                                "workstations");
1172 }
1173
1174 /*
1175  * List stuff
1176  */
1177
1178 static int net_sam_list(int argc, const char **argv)
1179 {
1180         struct functable2 func[] = {
1181                 { "users", net_sam_list_users,
1182                   "List SAM users" },
1183                 { "groups", net_sam_list_groups,
1184                   "List SAM groups" },
1185                 { "localgroups", net_sam_list_localgroups,
1186                   "List SAM local groups" },
1187                 { "builtin", net_sam_list_builtin,
1188                   "List builtin groups" },
1189                 { "workstations", net_sam_list_workstations,
1190                   "List domain member workstations" },
1191                 {NULL, NULL}
1192         };
1193
1194         return net_run_function2(argc, argv, "net sam list", func);
1195 }
1196
1197 /*
1198  * Show details of SAM entries
1199  */
1200
1201 static int net_sam_show(int argc, const char **argv)
1202 {
1203         DOM_SID sid;
1204         enum lsa_SidType type;
1205         const char *dom, *name;
1206
1207         if (argc != 1) {
1208                 d_fprintf(stderr, "usage: net sam show <name>\n");
1209                 return -1;
1210         }
1211
1212         if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_LOCAL,
1213                          &dom, &name, &sid, &type)) {
1214                 d_fprintf(stderr, "Could not find name %s\n", argv[0]);
1215                 return -1;
1216         }
1217
1218         d_printf("%s\\%s is a %s with SID %s\n", dom, name,
1219                  sid_type_lookup(type), sid_string_tos(&sid));
1220
1221         return 0;
1222 }
1223
1224 #ifdef HAVE_LDAP
1225
1226 /*
1227  * Init an LDAP tree with default users and Groups
1228  * if ldapsam:editposix is enabled
1229  */
1230
1231 static int net_sam_provision(int argc, const char **argv)
1232 {
1233         TALLOC_CTX *tc;
1234         char *ldap_bk;
1235         char *ldap_uri = NULL;
1236         char *p;
1237         struct smbldap_state *ls;
1238         GROUP_MAP gmap;
1239         DOM_SID gsid;
1240         gid_t domusers_gid = -1;
1241         gid_t domadmins_gid = -1;
1242         struct samu *samuser;
1243         struct passwd *pwd;
1244
1245         tc = talloc_new(NULL);
1246         if (!tc) {
1247                 d_fprintf(stderr, "Out of Memory!\n");
1248                 return -1;
1249         }
1250
1251         if ((ldap_bk = talloc_strdup(tc, lp_passdb_backend())) == NULL) {
1252                 d_fprintf(stderr, "talloc failed\n");
1253                 talloc_free(tc);
1254                 return -1;
1255         }
1256         p = strchr(ldap_bk, ':');
1257         if (p) {
1258                 *p = 0;
1259                 ldap_uri = talloc_strdup(tc, p+1);
1260                 trim_char(ldap_uri, ' ', ' ');
1261         }
1262
1263         trim_char(ldap_bk, ' ', ' ');
1264                 
1265         if (strcmp(ldap_bk, "ldapsam") != 0) {
1266                 d_fprintf(stderr, "Provisioning works only with ldapsam backend\n");
1267                 goto failed;
1268         }
1269         
1270         if (!lp_parm_bool(-1, "ldapsam", "trusted", False) ||
1271             !lp_parm_bool(-1, "ldapsam", "editposix", False)) {
1272
1273                 d_fprintf(stderr, "Provisioning works only if ldapsam:trusted"
1274                                   " and ldapsam:editposix are enabled.\n");
1275                 goto failed;
1276         }
1277
1278         if (!winbind_ping()) {
1279                 d_fprintf(stderr, "winbind seems not to run. Provisioning "
1280                           "LDAP only works when winbind runs.\n");
1281                 goto failed;
1282         }
1283
1284         if (!NT_STATUS_IS_OK(smbldap_init(tc, NULL, ldap_uri, &ls))) {
1285                 d_fprintf(stderr, "Unable to connect to the LDAP server.\n");
1286                 goto failed;
1287         }
1288
1289         d_printf("Checking for Domain Users group.\n");
1290
1291         sid_compose(&gsid, get_global_sam_sid(), DOMAIN_GROUP_RID_USERS);
1292
1293         if (!pdb_getgrsid(&gmap, gsid)) {
1294                 LDAPMod **mods = NULL;
1295                 char *dn;
1296                 char *uname;
1297                 char *wname;
1298                 char *gidstr;
1299                 char *gtype;
1300                 int rc;
1301
1302                 d_printf("Adding the Domain Users group.\n");
1303
1304                 /* lets allocate a new groupid for this group */
1305                 if (!winbind_allocate_gid(&domusers_gid)) {
1306                         d_fprintf(stderr, "Unable to allocate a new gid to create Domain Users group!\n");
1307                         goto domu_done;
1308                 }
1309
1310                 uname = talloc_strdup(tc, "domusers");
1311                 wname = talloc_strdup(tc, "Domain Users");
1312                 dn = talloc_asprintf(tc, "cn=%s,%s", "domusers", lp_ldap_group_suffix());
1313                 gidstr = talloc_asprintf(tc, "%d", domusers_gid);
1314                 gtype = talloc_asprintf(tc, "%d", SID_NAME_DOM_GRP);
1315
1316                 if (!uname || !wname || !dn || !gidstr || !gtype) {
1317                         d_fprintf(stderr, "Out of Memory!\n");
1318                         goto failed;
1319                 }
1320
1321                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXGROUP);
1322                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
1323                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", uname);
1324                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", wname);
1325                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
1326                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid",
1327                                 sid_string_talloc(tc, &gsid));
1328                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", gtype);
1329
1330                 talloc_autofree_ldapmod(tc, mods);
1331
1332                 rc = smbldap_add(ls, dn, mods);
1333
1334                 if (rc != LDAP_SUCCESS) {
1335                         d_fprintf(stderr, "Failed to add Domain Users group to ldap directory\n");
1336                 }
1337         } else {
1338                 domusers_gid = gmap.gid;
1339                 d_printf("found!\n");
1340         }       
1341
1342 domu_done:
1343
1344         d_printf("Checking for Domain Admins group.\n");
1345
1346         sid_compose(&gsid, get_global_sam_sid(), DOMAIN_GROUP_RID_ADMINS);
1347
1348         if (!pdb_getgrsid(&gmap, gsid)) {
1349                 LDAPMod **mods = NULL;
1350                 char *dn;
1351                 char *uname;
1352                 char *wname;
1353                 char *gidstr;
1354                 char *gtype;
1355                 int rc;
1356
1357                 d_printf("Adding the Domain Admins group.\n");
1358
1359                 /* lets allocate a new groupid for this group */
1360                 if (!winbind_allocate_gid(&domadmins_gid)) {
1361                         d_fprintf(stderr, "Unable to allocate a new gid to create Domain Admins group!\n");
1362                         goto doma_done;
1363                 }
1364
1365                 uname = talloc_strdup(tc, "domadmins");
1366                 wname = talloc_strdup(tc, "Domain Admins");
1367                 dn = talloc_asprintf(tc, "cn=%s,%s", "domadmins", lp_ldap_group_suffix());
1368                 gidstr = talloc_asprintf(tc, "%d", domadmins_gid);
1369                 gtype = talloc_asprintf(tc, "%d", SID_NAME_DOM_GRP);
1370
1371                 if (!uname || !wname || !dn || !gidstr || !gtype) {
1372                         d_fprintf(stderr, "Out of Memory!\n");
1373                         goto failed;
1374                 }
1375
1376                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXGROUP);
1377                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
1378                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", uname);
1379                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", wname);
1380                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
1381                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid",
1382                                 sid_string_talloc(tc, &gsid));
1383                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", gtype);
1384
1385                 talloc_autofree_ldapmod(tc, mods);
1386
1387                 rc = smbldap_add(ls, dn, mods);
1388
1389                 if (rc != LDAP_SUCCESS) {
1390                         d_fprintf(stderr, "Failed to add Domain Admins group to ldap directory\n");
1391                 }
1392         } else {
1393                 domadmins_gid = gmap.gid;
1394                 d_printf("found!\n");
1395         }
1396
1397 doma_done:
1398
1399         d_printf("Check for Administrator account.\n");
1400
1401         samuser = samu_new(tc);
1402         if (!samuser) {
1403                 d_fprintf(stderr, "Out of Memory!\n");
1404                 goto failed;
1405         }
1406
1407         if (!pdb_getsampwnam(samuser, "Administrator")) {
1408                 LDAPMod **mods = NULL;
1409                 DOM_SID sid;
1410                 char *dn;
1411                 char *name;
1412                 char *uidstr;
1413                 char *gidstr;
1414                 char *shell;
1415                 char *dir;
1416                 uid_t uid;
1417                 int rc;
1418                 
1419                 d_printf("Adding the Administrator user.\n");
1420
1421                 if (domadmins_gid == -1) {
1422                         d_fprintf(stderr, "Can't create Administrator user, Domain Admins group not available!\n");
1423                         goto done;
1424                 }
1425                 if (!winbind_allocate_uid(&uid)) {
1426                         d_fprintf(stderr, "Unable to allocate a new uid to create the Administrator user!\n");
1427                         goto done;
1428                 }
1429                 name = talloc_strdup(tc, "Administrator");
1430                 dn = talloc_asprintf(tc, "uid=Administrator,%s", lp_ldap_user_suffix());
1431                 uidstr = talloc_asprintf(tc, "%d", uid);
1432                 gidstr = talloc_asprintf(tc, "%d", domadmins_gid);
1433                 dir = talloc_sub_specified(tc, lp_template_homedir(),
1434                                                 "Administrator",
1435                                                 get_global_sam_name(),
1436                                                 uid, domadmins_gid);
1437                 shell = talloc_sub_specified(tc, lp_template_shell(),
1438                                                 "Administrator",
1439                                                 get_global_sam_name(),
1440                                                 uid, domadmins_gid);
1441
1442                 if (!name || !dn || !uidstr || !gidstr || !dir || !shell) {
1443                         d_fprintf(stderr, "Out of Memory!\n");
1444                         goto failed;
1445                 }
1446
1447                 sid_compose(&sid, get_global_sam_sid(), DOMAIN_USER_RID_ADMIN);
1448
1449                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_ACCOUNT);
1450                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXACCOUNT);
1451                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT);
1452                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "uid", name);
1453                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", name);
1454                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", name);
1455                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "uidNumber", uidstr);
1456                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
1457                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "homeDirectory", dir);
1458                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "loginShell", shell);
1459                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSID",
1460                                 sid_string_talloc(tc, &sid));
1461                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaAcctFlags",
1462                                 pdb_encode_acct_ctrl(ACB_NORMAL|ACB_DISABLED,
1463                                 NEW_PW_FORMAT_SPACE_PADDED_LEN));
1464
1465                 talloc_autofree_ldapmod(tc, mods);
1466
1467                 rc = smbldap_add(ls, dn, mods);
1468
1469                 if (rc != LDAP_SUCCESS) {
1470                         d_fprintf(stderr, "Failed to add Administrator user to ldap directory\n");
1471                 }
1472         } else {
1473                 d_printf("found!\n");
1474         }
1475
1476         d_printf("Checking for Guest user.\n");
1477
1478         samuser = samu_new(tc);
1479         if (!samuser) {
1480                 d_fprintf(stderr, "Out of Memory!\n");
1481                 goto failed;
1482         }
1483
1484         if (!pdb_getsampwnam(samuser, lp_guestaccount())) {
1485                 LDAPMod **mods = NULL;
1486                 DOM_SID sid;
1487                 char *dn;
1488                 char *uidstr;
1489                 char *gidstr;
1490                 int rc;
1491                 
1492                 d_printf("Adding the Guest user.\n");
1493
1494                 pwd = getpwnam_alloc(tc, lp_guestaccount());
1495
1496                 if (!pwd) {
1497                         if (domusers_gid == -1) {
1498                                 d_fprintf(stderr, "Can't create Guest user, Domain Users group not available!\n");
1499                                 goto done;
1500                         }
1501                         if ((pwd = talloc(tc, struct passwd)) == NULL) {
1502                                 d_fprintf(stderr, "talloc failed\n");
1503                                 goto done;
1504                         }
1505                         pwd->pw_name = talloc_strdup(pwd, lp_guestaccount());
1506                         if (!winbind_allocate_uid(&(pwd->pw_uid))) {
1507                                 d_fprintf(stderr, "Unable to allocate a new uid to create the Guest user!\n");
1508                                 goto done;
1509                         }
1510                         pwd->pw_gid = domusers_gid;
1511                         pwd->pw_dir = talloc_strdup(tc, "/");
1512                         pwd->pw_shell = talloc_strdup(tc, "/bin/false");
1513                         if (!pwd->pw_dir || !pwd->pw_shell) {
1514                                 d_fprintf(stderr, "Out of Memory!\n");
1515                                 goto failed;
1516                         }
1517                 }
1518
1519                 sid_compose(&sid, get_global_sam_sid(), DOMAIN_USER_RID_GUEST);
1520
1521                 dn = talloc_asprintf(tc, "uid=%s,%s", pwd->pw_name, lp_ldap_user_suffix ());
1522                 uidstr = talloc_asprintf(tc, "%d", pwd->pw_uid);
1523                 gidstr = talloc_asprintf(tc, "%d", pwd->pw_gid);
1524                 if (!dn || !uidstr || !gidstr) {
1525                         d_fprintf(stderr, "Out of Memory!\n");
1526                         goto failed;
1527                 }
1528
1529                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_ACCOUNT);
1530                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXACCOUNT);
1531                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT);
1532                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "uid", pwd->pw_name);
1533                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", pwd->pw_name);
1534                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", pwd->pw_name);
1535                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "uidNumber", uidstr);
1536                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
1537                 if ((pwd->pw_dir != NULL) && (pwd->pw_dir[0] != '\0')) {
1538                         smbldap_set_mod(&mods, LDAP_MOD_ADD, "homeDirectory", pwd->pw_dir);
1539                 }
1540                 if ((pwd->pw_shell != NULL) && (pwd->pw_shell[0] != '\0')) {
1541                         smbldap_set_mod(&mods, LDAP_MOD_ADD, "loginShell", pwd->pw_shell);
1542                 }
1543                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSID",
1544                                 sid_string_talloc(tc, &sid));
1545                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaAcctFlags",
1546                                 pdb_encode_acct_ctrl(ACB_NORMAL|ACB_DISABLED,
1547                                 NEW_PW_FORMAT_SPACE_PADDED_LEN));
1548
1549                 talloc_autofree_ldapmod(tc, mods);
1550
1551                 rc = smbldap_add(ls, dn, mods);
1552
1553                 if (rc != LDAP_SUCCESS) {
1554                         d_fprintf(stderr, "Failed to add Guest user to ldap directory\n");
1555                 }
1556         } else {
1557                 d_printf("found!\n");
1558         }
1559
1560         d_printf("Checking Guest's group.\n");
1561
1562         pwd = getpwnam_alloc(NULL, lp_guestaccount());
1563         if (!pwd) {
1564                 d_fprintf(stderr, "Failed to find just created Guest account!\n"
1565                                   "   Is nss properly configured?!\n");
1566                 goto failed;
1567         }
1568
1569         if (pwd->pw_gid == domusers_gid) {
1570                 d_printf("found!\n");
1571                 goto done;
1572         }
1573
1574         if (!pdb_getgrgid(&gmap, pwd->pw_gid)) {
1575                 LDAPMod **mods = NULL;
1576                 char *dn;
1577                 char *uname;
1578                 char *wname;
1579                 char *gidstr;
1580                 char *gtype;
1581                 int rc;
1582
1583                 d_printf("Adding the Domain Guests group.\n");
1584
1585                 uname = talloc_strdup(tc, "domguests");
1586                 wname = talloc_strdup(tc, "Domain Guests");
1587                 dn = talloc_asprintf(tc, "cn=%s,%s", "domguests", lp_ldap_group_suffix());
1588                 gidstr = talloc_asprintf(tc, "%d", pwd->pw_gid);
1589                 gtype = talloc_asprintf(tc, "%d", SID_NAME_DOM_GRP);
1590
1591                 if (!uname || !wname || !dn || !gidstr || !gtype) {
1592                         d_fprintf(stderr, "Out of Memory!\n");
1593                         goto failed;
1594                 }
1595
1596                 sid_compose(&gsid, get_global_sam_sid(), DOMAIN_GROUP_RID_GUESTS);
1597
1598                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXGROUP);
1599                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
1600                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", uname);
1601                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", wname);
1602                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
1603                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid",
1604                                 sid_string_talloc(tc, &gsid));
1605                 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", gtype);
1606
1607                 talloc_autofree_ldapmod(tc, mods);
1608
1609                 rc = smbldap_add(ls, dn, mods);
1610
1611                 if (rc != LDAP_SUCCESS) {
1612                         d_fprintf(stderr, "Failed to add Domain Guests group to ldap directory\n");
1613                 }
1614         } else {
1615                 d_printf("found!\n");
1616         }
1617
1618
1619 done:
1620         talloc_free(tc);
1621         return 0;
1622
1623 failed:
1624         talloc_free(tc);
1625         return -1;
1626 }
1627
1628 #endif
1629
1630 /***********************************************************
1631  migrated functionality from smbgroupedit
1632  **********************************************************/
1633 int net_sam(int argc, const char **argv)
1634 {
1635         struct functable2 func[] = {
1636                 { "createbuiltingroup", net_sam_createbuiltingroup,
1637                   "Create a new BUILTIN group" },
1638                 { "createlocalgroup", net_sam_createlocalgroup,
1639                   "Create a new local group" },
1640                 { "deletelocalgroup", net_sam_deletelocalgroup,
1641                   "Delete an existing local group" },
1642                 { "mapunixgroup", net_sam_mapunixgroup,
1643                   "Map a unix group to a domain group" },
1644                 { "unmapunixgroup", net_sam_unmapunixgroup,
1645                   "Remove a group mapping of an unix group to a domain group" },
1646                 { "addmem", net_sam_addmem,
1647                   "Add a member to a group" },
1648                 { "delmem", net_sam_delmem,
1649                   "Delete a member from a group" },
1650                 { "listmem", net_sam_listmem,
1651                   "List group members" },
1652                 { "list", net_sam_list,
1653                   "List users, groups and local groups" },
1654                 { "show", net_sam_show,
1655                   "Show details of a SAM entry" },
1656                 { "set", net_sam_set,
1657                   "Set details of a SAM account" },
1658                 { "policy", net_sam_policy,
1659                   "Set account policies" },
1660                 { "rights", net_sam_rights,
1661                   "Manipulate user privileges" },
1662 #ifdef HAVE_LDAP
1663                 { "provision", net_sam_provision,
1664                   "Provision a clean User Database" },
1665 #endif
1666                 { NULL, NULL, NULL }
1667         };
1668
1669         if (getuid() != 0) {
1670                 d_fprintf(stderr, "You are not root, most things won't "
1671                           "work\n");
1672         }
1673         
1674         return net_run_function2(argc, argv, "net sam", func);
1675 }
1676