2 * Unix SMB/CIFS implementation.
3 * Local SAM access routines
4 * Copyright (C) Volker Lendecke 2006
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.
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.
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/>.
22 #include "utils/net.h"
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))
32 struct samu *sam_acct = NULL;
34 enum lsa_SidType type;
35 const char *dom, *name;
39 d_fprintf(stderr, "usage: net sam set %s <user> <value>\n",
44 if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_ISOLATED,
45 &dom, &name, &sid, &type)) {
46 d_fprintf(stderr, "Could not find name %s\n", argv[0]);
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));
56 if ( !(sam_acct = samu_new( NULL )) ) {
57 d_fprintf(stderr, "Internal error\n");
61 if (!pdb_getsampwsid(sam_acct, &sid)) {
62 d_fprintf(stderr, "Loading user %s failed\n", argv[0]);
66 if (!fn(sam_acct, argv[1], PDB_CHANGED)) {
67 d_fprintf(stderr, "Internal error\n");
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));
78 TALLOC_FREE(sam_acct);
80 d_printf("Updated %s for %s\\%s to %s\n", field, dom, name, argv[1]);
84 static int net_sam_set_fullname(int argc, const char **argv)
86 return net_sam_userset(argc, argv, "fullname",
90 static int net_sam_set_logonscript(int argc, const char **argv)
92 return net_sam_userset(argc, argv, "logonscript",
93 pdb_set_logon_script);
96 static int net_sam_set_profilepath(int argc, const char **argv)
98 return net_sam_userset(argc, argv, "profilepath",
99 pdb_set_profile_path);
102 static int net_sam_set_homedrive(int argc, const char **argv)
104 return net_sam_userset(argc, argv, "homedrive",
108 static int net_sam_set_homedir(int argc, const char **argv)
110 return net_sam_userset(argc, argv, "homedir",
114 static int net_sam_set_workstations(int argc, const char **argv)
116 return net_sam_userset(argc, argv, "workstations",
117 pdb_set_workstations);
124 static int net_sam_set_userflag(int argc, const char **argv, const char *field,
127 struct samu *sam_acct = NULL;
129 enum lsa_SidType type;
130 const char *dom, *name;
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",
141 if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_ISOLATED,
142 &dom, &name, &sid, &type)) {
143 d_fprintf(stderr, "Could not find name %s\n", argv[0]);
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));
153 if ( !(sam_acct = samu_new( NULL )) ) {
154 d_fprintf(stderr, "Internal error\n");
158 if (!pdb_getsampwsid(sam_acct, &sid)) {
159 d_fprintf(stderr, "Loading user %s failed\n", argv[0]);
163 acct_flags = pdb_get_acct_ctrl(sam_acct);
165 if (strequal(argv[1], "yes")) {
171 pdb_set_acct_ctrl(sam_acct, acct_flags, PDB_CHANGED);
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));
180 TALLOC_FREE(sam_acct);
182 d_fprintf(stderr, "Updated flag %s for %s\\%s to %s\n", field, dom,
187 static int net_sam_set_disabled(int argc, const char **argv)
189 return net_sam_set_userflag(argc, argv, "disabled", ACB_DISABLED);
192 static int net_sam_set_pwnotreq(int argc, const char **argv)
194 return net_sam_set_userflag(argc, argv, "pwnotreq", ACB_PWNOTREQ);
197 static int net_sam_set_autolock(int argc, const char **argv)
199 return net_sam_set_userflag(argc, argv, "autolock", ACB_AUTOLOCK);
202 static int net_sam_set_pwnoexp(int argc, const char **argv)
204 return net_sam_set_userflag(argc, argv, "pwnoexp", ACB_PWNOEXP);
208 * Set pass last change time, based on force pass change now
211 static int net_sam_set_pwdmustchangenow(int argc, const char **argv)
213 struct samu *sam_acct = NULL;
215 enum lsa_SidType type;
216 const char *dom, *name;
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");
225 if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_ISOLATED,
226 &dom, &name, &sid, &type)) {
227 d_fprintf(stderr, "Could not find name %s\n", argv[0]);
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));
237 if ( !(sam_acct = samu_new( NULL )) ) {
238 d_fprintf(stderr, "Internal error\n");
242 if (!pdb_getsampwsid(sam_acct, &sid)) {
243 d_fprintf(stderr, "Loading user %s failed\n", argv[0]);
247 if (strequal(argv[1], "yes")) {
248 pdb_set_pass_last_set_time(sam_acct, 0, PDB_CHANGED);
250 pdb_set_pass_last_set_time(sam_acct, time(NULL), PDB_CHANGED);
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));
260 TALLOC_FREE(sam_acct);
262 d_fprintf(stderr, "Updated 'user must change password at next logon' for %s\\%s to %s\n", dom,
269 * Set a user's or a group's comment
272 static int net_sam_set_comment(int argc, const char **argv)
276 enum lsa_SidType type;
277 const char *dom, *name;
281 d_fprintf(stderr, "usage: net sam set comment <name> "
286 if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_ISOLATED,
287 &dom, &name, &sid, &type)) {
288 d_fprintf(stderr, "Could not find name %s\n", argv[0]);
292 if (type == SID_NAME_USER) {
293 return net_sam_userset(argc, argv, "comment",
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));
304 if (!pdb_getgrsid(&map, sid)) {
305 d_fprintf(stderr, "Could not load group %s\n", argv[0]);
309 fstrcpy(map.comment, argv[1]);
311 status = pdb_update_group_mapping_entry(&map);
313 if (!NT_STATUS_IS_OK(status)) {
314 d_fprintf(stderr, "Updating group mapping entry failed with "
315 "%s\n", nt_errstr(status));
319 d_printf("Updated comment of group %s\\%s to %s\n", dom, name,
325 static int net_sam_set(int argc, const char **argv)
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" },
355 return net_run_function2(argc, argv, "net sam set", func);
359 * Manage account policies
362 static int net_sam_policy_set(int argc, const char **argv)
364 const char *account_policy = NULL;
366 uint32 old_value = 0;
371 d_fprintf(stderr, "usage: net sam policy set "
372 "\"<account policy>\" <value> \n");
376 account_policy = argv[0];
377 field = account_policy_name_to_fieldnum(account_policy);
379 if (strequal(argv[1], "forever") || strequal(argv[1], "never")
380 || strequal(argv[1], "off")) {
384 value = strtoul(argv[1], &endptr, 10);
386 if ((endptr == argv[1]) || (endptr[0] != '\0')) {
387 d_printf("Unable to set policy \"%s\"! Invalid value "
389 account_policy, argv[1]);
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");
402 for (i=0; i<count; i++) {
403 d_fprintf(stderr, "%s\n", names[i]);
410 if (!pdb_get_account_policy(field, &old_value)) {
411 d_fprintf(stderr, "Valid account policy, but unable to fetch "
414 d_printf("Account policy \"%s\" value was: %d\n", account_policy,
418 if (!pdb_set_account_policy(field, value)) {
419 d_fprintf(stderr, "Valid account policy, but unable to "
423 d_printf("Account policy \"%s\" value is now: %d\n", account_policy,
430 static int net_sam_policy_show(int argc, const char **argv)
432 const char *account_policy = NULL;
437 d_fprintf(stderr, "usage: net sam policy show"
438 " \"<account policy>\" \n");
442 account_policy = argv[0];
443 field = account_policy_name_to_fieldnum(account_policy);
449 account_policy_names_list(&names, &count);
450 d_fprintf(stderr, "No account policy by that name!\n");
452 d_fprintf(stderr, "Valid account policies "
454 for (i=0; i<count; i++) {
455 d_fprintf(stderr, "%s\n", names[i]);
462 if (!pdb_get_account_policy(field, &old_value)) {
463 fprintf(stderr, "Valid account policy, but unable to "
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,
475 static int net_sam_policy_list(int argc, const char **argv)
480 account_policy_names_list(&names, &count);
482 d_fprintf(stderr, "Valid account policies "
484 for (i = 0; i < count ; i++) {
485 d_fprintf(stderr, "%s\n", names[i]);
492 static int net_sam_policy(int argc, const char **argv)
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" },
504 return net_run_function2(argc, argv, "net sam policy", func);
508 * Map a unix group to a domain group
511 static NTSTATUS map_unix_group(const struct group *grp, GROUP_MAP *pmap)
515 const char *grpname, *dom, *name;
518 if (pdb_getgrgid(&map, grp->gr_gid)) {
519 return NT_STATUS_GROUP_EXISTS;
522 map.gid = grp->gr_gid;
523 grpname = grp->gr_name;
525 if (lookup_name(talloc_tos(), grpname, LOOKUP_NAME_ISOLATED,
526 &dom, &name, NULL, NULL)) {
528 const char *tmp = talloc_asprintf(
529 talloc_tos(), "Unix Group %s", grp->gr_name);
531 DEBUG(5, ("%s exists as %s\\%s, retrying as \"%s\"\n",
532 grpname, dom, name, tmp));
536 if (lookup_name(talloc_tos(), grpname, LOOKUP_NAME_ISOLATED,
537 NULL, NULL, NULL, NULL)) {
538 DEBUG(3, ("\"%s\" exists, can't map it\n", grp->gr_name));
539 return NT_STATUS_GROUP_EXISTS;
542 fstrcpy(map.nt_name, grpname);
544 if (pdb_rid_algorithm()) {
545 rid = algorithmic_pdb_gid_to_group_rid( grp->gr_gid );
547 if (!pdb_new_rid(&rid)) {
548 DEBUG(3, ("Could not get a new RID for %s\n",
550 return NT_STATUS_ACCESS_DENIED;
554 sid_compose(&map.sid, get_global_sam_sid(), rid);
555 map.sid_name_use = SID_NAME_DOM_GRP;
556 fstrcpy(map.comment, talloc_asprintf(talloc_tos(), "Unix Group %s",
559 status = pdb_add_group_mapping_entry(&map);
560 if (NT_STATUS_IS_OK(status)) {
566 static int net_sam_mapunixgroup(int argc, const char **argv)
573 d_fprintf(stderr, "usage: net sam mapunixgroup <name>\n");
577 grp = getgrnam(argv[0]);
579 d_fprintf(stderr, "Could not find group %s\n", argv[0]);
583 status = map_unix_group(grp, &map);
585 if (!NT_STATUS_IS_OK(status)) {
586 d_fprintf(stderr, "Mapping group %s failed with %s\n",
587 argv[0], nt_errstr(status));
591 d_printf("Mapped unix group %s to SID %s\n", argv[0],
592 sid_string_static(&map.sid));
598 * Remove a group mapping
601 static NTSTATUS unmap_unix_group(const struct group *grp, GROUP_MAP *pmap)
608 map.gid = grp->gr_gid;
609 grpname = grp->gr_name;
611 if (!lookup_name(talloc_tos(), grpname, LOOKUP_NAME_ISOLATED,
612 NULL, NULL, NULL, NULL)) {
613 DEBUG(3, ("\"%s\" does not exist, can't unmap it\n", grp->gr_name));
614 return NT_STATUS_NO_SUCH_GROUP;
617 fstrcpy(map.nt_name, grpname);
619 if (!pdb_gid_to_sid(map.gid, &dom_sid)) {
620 return NT_STATUS_UNSUCCESSFUL;
623 status = pdb_delete_group_mapping_entry(dom_sid);
628 static int net_sam_unmapunixgroup(int argc, const char **argv)
635 d_fprintf(stderr, "usage: net sam unmapunixgroup <name>\n");
639 grp = getgrnam(argv[0]);
641 d_fprintf(stderr, "Could not find mapping for group %s.\n", argv[0]);
645 status = unmap_unix_group(grp, &map);
647 if (!NT_STATUS_IS_OK(status)) {
648 d_fprintf(stderr, "Unmapping group %s failed with %s.\n",
649 argv[0], nt_errstr(status));
653 d_printf("Unmapped unix group %s.\n", argv[0]);
659 * Create a local group
662 static int net_sam_createlocalgroup(int argc, const char **argv)
668 d_fprintf(stderr, "usage: net sam createlocalgroup <name>\n");
672 if (!winbind_ping()) {
673 d_fprintf(stderr, "winbind seems not to run. createlocalgroup "
674 "only works when winbind runs.\n");
678 status = pdb_create_alias(argv[0], &rid);
680 if (!NT_STATUS_IS_OK(status)) {
681 d_fprintf(stderr, "Creating %s failed with %s\n",
682 argv[0], nt_errstr(status));
686 d_printf("Created local group %s with RID %d\n", argv[0], rid);
692 * Delete a local group
695 static int net_sam_deletelocalgroup(int argc, const char **argv)
698 enum lsa_SidType type;
699 const char *dom, *name;
703 d_fprintf(stderr, "usage: net sam deletelocalgroup <name>\n");
707 if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_ISOLATED,
708 &dom, &name, &sid, &type)) {
709 d_fprintf(stderr, "Could not find %s.\n", argv[0]);
713 if (type != SID_NAME_ALIAS) {
714 d_fprintf(stderr, "%s is a %s, not a local group.\n", argv[0],
715 sid_type_lookup(type));
719 status = pdb_delete_alias(&sid);
721 if (!NT_STATUS_IS_OK(status)) {
722 d_fprintf(stderr, "Deleting local group %s failed with %s\n",
723 argv[0], nt_errstr(status));
727 d_printf("Deleted local group %s.\n", argv[0]);
733 * Create a local group
736 static int net_sam_createbuiltingroup(int argc, const char **argv)
740 enum lsa_SidType type;
745 d_fprintf(stderr, "usage: net sam createbuiltingroup <name>\n");
749 if (!winbind_ping()) {
750 d_fprintf(stderr, "winbind seems not to run. createlocalgroup "
751 "only works when winbind runs.\n");
755 /* validate the name and get the group */
757 fstrcpy( groupname, "BUILTIN\\" );
758 fstrcat( groupname, argv[0] );
760 if ( !lookup_name(talloc_tos(), groupname, LOOKUP_NAME_ALL, NULL,
761 NULL, &sid, &type)) {
762 d_fprintf(stderr, "%s is not a BUILTIN group\n", argv[0]);
766 if ( !sid_peek_rid( &sid, &rid ) ) {
767 d_fprintf(stderr, "Failed to get RID for %s\n", argv[0]);
771 status = pdb_create_builtin_alias( rid );
773 if (!NT_STATUS_IS_OK(status)) {
774 d_fprintf(stderr, "Creating %s failed with %s\n",
775 argv[0], nt_errstr(status));
779 d_printf("Created BUILTIN group %s with RID %d\n", argv[0], rid);
788 static int net_sam_addmem(int argc, const char **argv)
790 const char *groupdomain, *groupname, *memberdomain, *membername;
791 DOM_SID group, member;
792 enum lsa_SidType grouptype, membertype;
796 d_fprintf(stderr, "usage: net sam addmem <group> <member>\n");
800 if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_ISOLATED,
801 &groupdomain, &groupname, &group, &grouptype)) {
802 d_fprintf(stderr, "Could not find group %s\n", argv[0]);
806 /* check to see if the member to be added is a name or a SID */
808 if (!lookup_name(talloc_tos(), argv[1], LOOKUP_NAME_ISOLATED,
809 &memberdomain, &membername, &member, &membertype))
811 /* try it as a SID */
813 if ( !string_to_sid( &member, argv[1] ) ) {
814 d_fprintf(stderr, "Could not find member %s\n", argv[1]);
818 if ( !lookup_sid(talloc_tos(), &member, &memberdomain,
819 &membername, &membertype) )
821 d_fprintf(stderr, "Could not resolve SID %s\n", argv[1]);
826 if ((grouptype == SID_NAME_ALIAS) || (grouptype == SID_NAME_WKN_GRP)) {
827 if ((membertype != SID_NAME_USER) &&
828 (membertype != SID_NAME_DOM_GRP)) {
829 d_fprintf(stderr, "%s is a local group, only users "
830 "and domain groups can be added.\n"
831 "%s is a %s\n", argv[0], argv[1],
832 sid_type_lookup(membertype));
835 status = pdb_add_aliasmem(&group, &member);
837 if (!NT_STATUS_IS_OK(status)) {
838 d_fprintf(stderr, "Adding local group member failed "
839 "with %s\n", nt_errstr(status));
843 d_fprintf(stderr, "Can only add members to local groups so "
844 "far, %s is a %s\n", argv[0],
845 sid_type_lookup(grouptype));
849 d_printf("Added %s\\%s to %s\\%s\n", memberdomain, membername,
850 groupdomain, groupname);
856 * Delete a group member
859 static int net_sam_delmem(int argc, const char **argv)
861 const char *groupdomain, *groupname;
862 const char *memberdomain = NULL;
863 const char *membername = NULL;
864 DOM_SID group, member;
865 enum lsa_SidType grouptype;
869 d_fprintf(stderr, "usage: net sam delmem <group> <member>\n");
873 if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_ISOLATED,
874 &groupdomain, &groupname, &group, &grouptype)) {
875 d_fprintf(stderr, "Could not find group %s\n", argv[0]);
879 if (!lookup_name(talloc_tos(), argv[1], LOOKUP_NAME_ISOLATED,
880 &memberdomain, &membername, &member, NULL)) {
881 if (!string_to_sid(&member, argv[1])) {
882 d_fprintf(stderr, "Could not find member %s\n",
888 if ((grouptype == SID_NAME_ALIAS) ||
889 (grouptype == SID_NAME_WKN_GRP)) {
890 status = pdb_del_aliasmem(&group, &member);
892 if (!NT_STATUS_IS_OK(status)) {
893 d_fprintf(stderr, "Deleting local group member failed "
894 "with %s\n", nt_errstr(status));
898 d_fprintf(stderr, "Can only delete members from local groups "
899 "so far, %s is a %s\n", argv[0],
900 sid_type_lookup(grouptype));
904 if (membername != NULL) {
905 d_printf("Deleted %s\\%s from %s\\%s\n",
906 memberdomain, membername, groupdomain, groupname);
908 d_printf("Deleted %s from %s\\%s\n",
909 sid_string_static(&member), groupdomain, groupname);
919 static int net_sam_listmem(int argc, const char **argv)
921 const char *groupdomain, *groupname;
923 enum lsa_SidType grouptype;
927 d_fprintf(stderr, "usage: net sam listmem <group>\n");
931 if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_ISOLATED,
932 &groupdomain, &groupname, &group, &grouptype)) {
933 d_fprintf(stderr, "Could not find group %s\n", argv[0]);
937 if ((grouptype == SID_NAME_ALIAS) ||
938 (grouptype == SID_NAME_WKN_GRP)) {
939 DOM_SID *members = NULL;
940 size_t i, num_members = 0;
942 status = pdb_enum_aliasmem(&group, &members, &num_members);
944 if (!NT_STATUS_IS_OK(status)) {
945 d_fprintf(stderr, "Listing group members failed with "
946 "%s\n", nt_errstr(status));
950 d_printf("%s\\%s has %u members\n", groupdomain, groupname,
951 (unsigned int)num_members);
952 for (i=0; i<num_members; i++) {
953 const char *dom, *name;
954 if (lookup_sid(talloc_tos(), &members[i],
955 &dom, &name, NULL)) {
956 d_printf(" %s\\%s\n", dom, name);
959 sid_string_static(&members[i]));
963 TALLOC_FREE(members);
965 d_fprintf(stderr, "Can only list local group members so far.\n"
966 "%s is a %s\n", argv[0], sid_type_lookup(grouptype));
976 static int net_sam_do_list(int argc, const char **argv,
977 struct pdb_search *search, const char *what)
979 BOOL verbose = (argc == 1);
982 ((argc == 1) && !strequal(argv[0], "verbose"))) {
983 d_fprintf(stderr, "usage: net sam list %s [verbose]\n", what);
987 if (search == NULL) {
988 d_fprintf(stderr, "Could not start search\n");
993 struct samr_displayentry entry;
994 if (!search->next_entry(search, &entry)) {
998 d_printf("%s:%d:%s\n",
1003 d_printf("%s\n", entry.account_name);
1007 search->search_end(search);
1011 static int net_sam_list_users(int argc, const char **argv)
1013 return net_sam_do_list(argc, argv, pdb_search_users(ACB_NORMAL),
1017 static int net_sam_list_groups(int argc, const char **argv)
1019 return net_sam_do_list(argc, argv, pdb_search_groups(), "groups");
1022 static int net_sam_list_localgroups(int argc, const char **argv)
1024 return net_sam_do_list(argc, argv,
1025 pdb_search_aliases(get_global_sam_sid()),
1029 static int net_sam_list_builtin(int argc, const char **argv)
1031 return net_sam_do_list(argc, argv,
1032 pdb_search_aliases(&global_sid_Builtin),
1036 static int net_sam_list_workstations(int argc, const char **argv)
1038 return net_sam_do_list(argc, argv,
1039 pdb_search_users(ACB_WSTRUST),
1047 static int net_sam_list(int argc, const char **argv)
1049 struct functable2 func[] = {
1050 { "users", net_sam_list_users,
1052 { "groups", net_sam_list_groups,
1053 "List SAM groups" },
1054 { "localgroups", net_sam_list_localgroups,
1055 "List SAM local groups" },
1056 { "builtin", net_sam_list_builtin,
1057 "List builtin groups" },
1058 { "workstations", net_sam_list_workstations,
1059 "List domain member workstations" },
1063 return net_run_function2(argc, argv, "net sam list", func);
1067 * Show details of SAM entries
1070 static int net_sam_show(int argc, const char **argv)
1073 enum lsa_SidType type;
1074 const char *dom, *name;
1077 d_fprintf(stderr, "usage: net sam show <name>\n");
1081 if (!lookup_name(talloc_tos(), argv[0], LOOKUP_NAME_ISOLATED,
1082 &dom, &name, &sid, &type)) {
1083 d_fprintf(stderr, "Could not find name %s\n", argv[0]);
1087 d_printf("%s\\%s is a %s with SID %s\n", dom, name,
1088 sid_type_lookup(type), sid_string_static(&sid));
1096 * Init an LDAP tree with default users and Groups
1097 * if ldapsam:editposix is enabled
1100 static int net_sam_provision(int argc, const char **argv)
1104 char *ldap_uri = NULL;
1106 struct smbldap_state *ls;
1109 gid_t domusers_gid = -1;
1110 gid_t domadmins_gid = -1;
1111 struct samu *samuser;
1114 tc = talloc_new(NULL);
1116 d_fprintf(stderr, "Out of Memory!\n");
1120 if ((ldap_bk = talloc_strdup(tc, lp_passdb_backend())) == NULL) {
1121 d_fprintf(stderr, "talloc failed\n");
1125 p = strchr(ldap_bk, ':');
1128 ldap_uri = talloc_strdup(tc, p+1);
1129 trim_char(ldap_uri, ' ', ' ');
1132 trim_char(ldap_bk, ' ', ' ');
1134 if (strcmp(ldap_bk, "ldapsam") != 0) {
1135 d_fprintf(stderr, "Provisioning works only with ldapsam backend\n");
1139 if (!lp_parm_bool(-1, "ldapsam", "trusted", False) ||
1140 !lp_parm_bool(-1, "ldapsam", "editposix", False)) {
1142 d_fprintf(stderr, "Provisioning works only if ldapsam:trusted"
1143 " and ldapsam:editposix are enabled.\n");
1147 if (!winbind_ping()) {
1148 d_fprintf(stderr, "winbind seems not to run. Provisioning "
1149 "LDAP only works when winbind runs.\n");
1153 if (!NT_STATUS_IS_OK(smbldap_init(tc, NULL, ldap_uri, &ls))) {
1154 d_fprintf(stderr, "Unable to connect to the LDAP server.\n");
1158 d_printf("Checking for Domain Users group.\n");
1160 sid_compose(&gsid, get_global_sam_sid(), DOMAIN_GROUP_RID_USERS);
1162 if (!pdb_getgrsid(&gmap, gsid)) {
1163 LDAPMod **mods = NULL;
1171 d_printf("Adding the Domain Users group.\n");
1173 /* lets allocate a new groupid for this group */
1174 if (!winbind_allocate_gid(&domusers_gid)) {
1175 d_fprintf(stderr, "Unable to allocate a new gid to create Domain Users group!\n");
1179 uname = talloc_strdup(tc, "domusers");
1180 wname = talloc_strdup(tc, "Domain Users");
1181 dn = talloc_asprintf(tc, "cn=%s,%s", "domusers", lp_ldap_group_suffix());
1182 gidstr = talloc_asprintf(tc, "%d", domusers_gid);
1183 gtype = talloc_asprintf(tc, "%d", SID_NAME_DOM_GRP);
1185 if (!uname || !wname || !dn || !gidstr || !gtype) {
1186 d_fprintf(stderr, "Out of Memory!\n");
1190 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_POSIXGROUP);
1191 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
1192 smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", uname);
1193 smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", wname);
1194 smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
1195 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid", sid_string_static(&gsid));
1196 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", gtype);
1198 talloc_autofree_ldapmod(tc, mods);
1200 rc = smbldap_add(ls, dn, mods);
1202 if (rc != LDAP_SUCCESS) {
1203 d_fprintf(stderr, "Failed to add Domain Users group to ldap directory\n");
1206 domusers_gid = gmap.gid;
1207 d_printf("found!\n");
1212 d_printf("Checking for Domain Admins group.\n");
1214 sid_compose(&gsid, get_global_sam_sid(), DOMAIN_GROUP_RID_ADMINS);
1216 if (!pdb_getgrsid(&gmap, gsid)) {
1217 LDAPMod **mods = NULL;
1225 d_printf("Adding the Domain Admins group.\n");
1227 /* lets allocate a new groupid for this group */
1228 if (!winbind_allocate_gid(&domadmins_gid)) {
1229 d_fprintf(stderr, "Unable to allocate a new gid to create Domain Admins group!\n");
1233 uname = talloc_strdup(tc, "domadmins");
1234 wname = talloc_strdup(tc, "Domain Admins");
1235 dn = talloc_asprintf(tc, "cn=%s,%s", "domadmins", lp_ldap_group_suffix());
1236 gidstr = talloc_asprintf(tc, "%d", domadmins_gid);
1237 gtype = talloc_asprintf(tc, "%d", SID_NAME_DOM_GRP);
1239 if (!uname || !wname || !dn || !gidstr || !gtype) {
1240 d_fprintf(stderr, "Out of Memory!\n");
1244 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_POSIXGROUP);
1245 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
1246 smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", uname);
1247 smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", wname);
1248 smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
1249 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid", sid_string_static(&gsid));
1250 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", gtype);
1252 talloc_autofree_ldapmod(tc, mods);
1254 rc = smbldap_add(ls, dn, mods);
1256 if (rc != LDAP_SUCCESS) {
1257 d_fprintf(stderr, "Failed to add Domain Admins group to ldap directory\n");
1260 domadmins_gid = gmap.gid;
1261 d_printf("found!\n");
1266 d_printf("Check for Administrator account.\n");
1268 samuser = samu_new(tc);
1270 d_fprintf(stderr, "Out of Memory!\n");
1274 if (!pdb_getsampwnam(samuser, "Administrator")) {
1275 LDAPMod **mods = NULL;
1286 d_printf("Adding the Administrator user.\n");
1288 if (domadmins_gid == -1) {
1289 d_fprintf(stderr, "Can't create Administrator user, Domain Admins group not available!\n");
1292 if (!winbind_allocate_uid(&uid)) {
1293 d_fprintf(stderr, "Unable to allocate a new uid to create the Administrator user!\n");
1296 name = talloc_strdup(tc, "Administrator");
1297 dn = talloc_asprintf(tc, "uid=Administrator,%s", lp_ldap_user_suffix());
1298 uidstr = talloc_asprintf(tc, "%d", uid);
1299 gidstr = talloc_asprintf(tc, "%d", domadmins_gid);
1300 dir = talloc_sub_specified(tc, lp_template_homedir(),
1302 get_global_sam_name(),
1303 uid, domadmins_gid);
1304 shell = talloc_sub_specified(tc, lp_template_shell(),
1306 get_global_sam_name(),
1307 uid, domadmins_gid);
1309 if (!name || !dn || !uidstr || !gidstr || !dir || !shell) {
1310 d_fprintf(stderr, "Out of Memory!\n");
1314 sid_compose(&sid, get_global_sam_sid(), DOMAIN_USER_RID_ADMIN);
1316 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_ACCOUNT);
1317 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXACCOUNT);
1318 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT);
1319 smbldap_set_mod(&mods, LDAP_MOD_ADD, "uid", name);
1320 smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", name);
1321 smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", name);
1322 smbldap_set_mod(&mods, LDAP_MOD_ADD, "uidNumber", uidstr);
1323 smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
1324 smbldap_set_mod(&mods, LDAP_MOD_ADD, "homeDirectory", dir);
1325 smbldap_set_mod(&mods, LDAP_MOD_ADD, "loginShell", shell);
1326 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSID", sid_string_static(&sid));
1327 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaAcctFlags",
1328 pdb_encode_acct_ctrl(ACB_NORMAL|ACB_DISABLED,
1329 NEW_PW_FORMAT_SPACE_PADDED_LEN));
1331 talloc_autofree_ldapmod(tc, mods);
1333 rc = smbldap_add(ls, dn, mods);
1335 if (rc != LDAP_SUCCESS) {
1336 d_fprintf(stderr, "Failed to add Administrator user to ldap directory\n");
1339 d_printf("found!\n");
1342 d_printf("Checking for Guest user.\n");
1344 samuser = samu_new(tc);
1346 d_fprintf(stderr, "Out of Memory!\n");
1350 if (!pdb_getsampwnam(samuser, lp_guestaccount())) {
1351 LDAPMod **mods = NULL;
1358 d_printf("Adding the Guest user.\n");
1360 pwd = getpwnam_alloc(tc, lp_guestaccount());
1363 if (domusers_gid == -1) {
1364 d_fprintf(stderr, "Can't create Guest user, Domain Users group not available!\n");
1367 if ((pwd = talloc(tc, struct passwd)) == NULL) {
1368 d_fprintf(stderr, "talloc failed\n");
1371 pwd->pw_name = talloc_strdup(pwd, lp_guestaccount());
1372 if (!winbind_allocate_uid(&(pwd->pw_uid))) {
1373 d_fprintf(stderr, "Unable to allocate a new uid to create the Guest user!\n");
1376 pwd->pw_gid = domusers_gid;
1377 pwd->pw_dir = talloc_strdup(tc, "/");
1378 pwd->pw_shell = talloc_strdup(tc, "/bin/false");
1379 if (!pwd->pw_dir || !pwd->pw_shell) {
1380 d_fprintf(stderr, "Out of Memory!\n");
1385 sid_compose(&sid, get_global_sam_sid(), DOMAIN_USER_RID_GUEST);
1387 dn = talloc_asprintf(tc, "uid=%s,%s", pwd->pw_name, lp_ldap_user_suffix ());
1388 uidstr = talloc_asprintf(tc, "%d", pwd->pw_uid);
1389 gidstr = talloc_asprintf(tc, "%d", pwd->pw_gid);
1390 if (!dn || !uidstr || !gidstr) {
1391 d_fprintf(stderr, "Out of Memory!\n");
1395 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_ACCOUNT);
1396 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXACCOUNT);
1397 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT);
1398 smbldap_set_mod(&mods, LDAP_MOD_ADD, "uid", pwd->pw_name);
1399 smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", pwd->pw_name);
1400 smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", pwd->pw_name);
1401 smbldap_set_mod(&mods, LDAP_MOD_ADD, "uidNumber", uidstr);
1402 smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
1403 if ((pwd->pw_dir != NULL) && (pwd->pw_dir[0] != '\0')) {
1404 smbldap_set_mod(&mods, LDAP_MOD_ADD, "homeDirectory", pwd->pw_dir);
1406 if ((pwd->pw_shell != NULL) && (pwd->pw_shell[0] != '\0')) {
1407 smbldap_set_mod(&mods, LDAP_MOD_ADD, "loginShell", pwd->pw_shell);
1409 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSID", sid_string_static(&sid));
1410 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaAcctFlags",
1411 pdb_encode_acct_ctrl(ACB_NORMAL|ACB_DISABLED,
1412 NEW_PW_FORMAT_SPACE_PADDED_LEN));
1414 talloc_autofree_ldapmod(tc, mods);
1416 rc = smbldap_add(ls, dn, mods);
1418 if (rc != LDAP_SUCCESS) {
1419 d_fprintf(stderr, "Failed to add Guest user to ldap directory\n");
1422 d_printf("found!\n");
1425 d_printf("Checking Guest's group.\n");
1427 pwd = getpwnam_alloc(NULL, lp_guestaccount());
1429 d_fprintf(stderr, "Failed to find just created Guest account!\n"
1430 " Is nss properly configured?!\n");
1434 if (pwd->pw_gid == domusers_gid) {
1435 d_printf("found!\n");
1439 if (!pdb_getgrgid(&gmap, pwd->pw_gid)) {
1440 LDAPMod **mods = NULL;
1448 d_printf("Adding the Domain Guests group.\n");
1450 uname = talloc_strdup(tc, "domguests");
1451 wname = talloc_strdup(tc, "Domain Guests");
1452 dn = talloc_asprintf(tc, "cn=%s,%s", "domguests", lp_ldap_group_suffix());
1453 gidstr = talloc_asprintf(tc, "%d", pwd->pw_gid);
1454 gtype = talloc_asprintf(tc, "%d", SID_NAME_DOM_GRP);
1456 if (!uname || !wname || !dn || !gidstr || !gtype) {
1457 d_fprintf(stderr, "Out of Memory!\n");
1461 sid_compose(&gsid, get_global_sam_sid(), DOMAIN_GROUP_RID_GUESTS);
1463 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_POSIXGROUP);
1464 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
1465 smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", uname);
1466 smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", wname);
1467 smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
1468 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid", sid_string_static(&gsid));
1469 smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", gtype);
1471 talloc_autofree_ldapmod(tc, mods);
1473 rc = smbldap_add(ls, dn, mods);
1475 if (rc != LDAP_SUCCESS) {
1476 d_fprintf(stderr, "Failed to add Domain Guests group to ldap directory\n");
1479 d_printf("found!\n");
1494 /***********************************************************
1495 migrated functionality from smbgroupedit
1496 **********************************************************/
1497 int net_sam(int argc, const char **argv)
1499 struct functable2 func[] = {
1500 { "createbuiltingroup", net_sam_createbuiltingroup,
1501 "Create a new BUILTIN group" },
1502 { "createlocalgroup", net_sam_createlocalgroup,
1503 "Create a new local group" },
1504 { "deletelocalgroup", net_sam_deletelocalgroup,
1505 "Delete an existing local group" },
1506 { "mapunixgroup", net_sam_mapunixgroup,
1507 "Map a unix group to a domain group" },
1508 { "unmapunixgroup", net_sam_unmapunixgroup,
1509 "Remove a group mapping of an unix group to a domain group" },
1510 { "addmem", net_sam_addmem,
1511 "Add a member to a group" },
1512 { "delmem", net_sam_delmem,
1513 "Delete a member from a group" },
1514 { "listmem", net_sam_listmem,
1515 "List group members" },
1516 { "list", net_sam_list,
1517 "List users, groups and local groups" },
1518 { "show", net_sam_show,
1519 "Show details of a SAM entry" },
1520 { "set", net_sam_set,
1521 "Set details of a SAM account" },
1522 { "policy", net_sam_policy,
1523 "Set account policies" },
1525 { "provision", net_sam_provision,
1526 "Provision a clean User Database" },
1528 { NULL, NULL, NULL }
1531 /* we shouldn't have silly checks like this */
1532 if (getuid() != 0) {
1533 d_fprintf(stderr, "You must be root to edit the SAM "
1538 return net_run_function2(argc, argv, "net sam", func);