r17554: Cleanup
[bbaumbach/samba-autobuild/.git] / source3 / utils / net_sam.c
index ea0544abf3ae17188a5c4ea9976c2bbd3c8071a4..654c9ec5b2a3c4fee8c0f9ef18958f8dd0ec5a18 100644 (file)
@@ -454,6 +454,58 @@ static int net_sam_createlocalgroup(int argc, const char **argv)
        return 0;
 }
 
+/*
+ * Create a local group
+ */
+
+static int net_sam_createbuiltingroup(int argc, const char **argv)
+{
+       NTSTATUS status;
+       uint32 rid;
+       enum SID_NAME_USE type;
+       fstring groupname;
+       DOM_SID sid;
+
+       if (argc != 1) {
+               d_fprintf(stderr, "usage: net sam createbuiltingroup <name>\n");
+               return -1;
+       }
+
+       if (!winbind_ping()) {
+               d_fprintf(stderr, "winbind seems not to run. createlocalgroup "
+                         "only works when winbind runs.\n");
+               return -1;
+       }
+
+       /* validate the name and get the group */
+       
+       fstrcpy( groupname, "BUILTIN\\" );
+       fstrcat( groupname, argv[0] );
+       
+       if ( !lookup_name(tmp_talloc_ctx(), groupname, LOOKUP_NAME_ALL, NULL,
+                         NULL, &sid, &type)) {
+               d_fprintf(stderr, "%s is not a BUILTIN group\n", argv[0]);
+               return -1;
+       }
+       
+       if ( !sid_peek_rid( &sid, &rid ) ) {
+               d_fprintf(stderr, "Failed to get RID for %s\n", argv[0]);
+               return -1;
+       }
+
+       status = pdb_create_builtin_alias( rid );
+
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, "Creating %s failed with %s\n",
+                         argv[0], nt_errstr(status));
+               return -1;
+       }
+
+       d_printf("Created BUILTIN group %s with RID %d\n", argv[0], rid);
+
+       return 0;
+}
+
 /*
  * Add a group member
  */
@@ -476,10 +528,24 @@ static int net_sam_addmem(int argc, const char **argv)
                return -1;
        }
 
+       /* check to see if the member to be added is a name or a SID */
+
        if (!lookup_name(tmp_talloc_ctx(), argv[1], LOOKUP_NAME_ISOLATED,
-                        &memberdomain, &membername, &member, &membertype)) {
-               d_fprintf(stderr, "Could not find member %s\n", argv[1]);
-               return -1;
+                        &memberdomain, &membername, &member, &membertype))
+       {
+               /* try it as a SID */
+
+               if ( !string_to_sid( &member, argv[1] ) ) {
+                       d_fprintf(stderr, "Could not find member %s\n", argv[1]);
+                       return -1;
+               }
+
+               if ( !lookup_sid(tmp_talloc_ctx(), &member, &memberdomain, 
+                       &membername, &membertype) ) 
+               {
+                       d_fprintf(stderr, "Could not resolve SID %s\n", argv[1]);
+                       return -1;
+               }
        }
 
        if ((grouptype == SID_NAME_ALIAS) || (grouptype == SID_NAME_WKN_GRP)) {
@@ -505,8 +571,8 @@ static int net_sam_addmem(int argc, const char **argv)
                return -1;
        }
 
-       d_printf("Added %s\\%s to %s\\%s\n",
-                memberdomain, membername, groupdomain, groupname);
+       d_printf("Added %s\\%s to %s\\%s\n", memberdomain, membername, 
+               groupdomain, groupname);
 
        return 0;
 }
@@ -606,8 +672,8 @@ static int net_sam_listmem(int argc, const char **argv)
                        return -1;
                }
 
-               d_printf("%s\\%s has %d members\n", groupdomain, groupname,
-                        num_members);
+               d_printf("%s\\%s has %u members\n", groupdomain, groupname,
+                        (unsigned int)num_members);
                for (i=0; i<num_members; i++) {
                        const char *dom, *name;
                        if (lookup_sid(tmp_talloc_ctx(), &members[i],
@@ -747,12 +813,409 @@ static int net_sam_show(int argc, const char **argv)
        return 0;
 }
 
+#ifdef HAVE_LDAP
+
+/*
+ * Init an LDAP tree with default users and Groups
+ * if ldapsam:editposix is enabled
+ */
+
+static int net_sam_provision(int argc, const char **argv)
+{
+       TALLOC_CTX *tc;
+       char *ldap_bk;
+       char *ldap_uri = NULL;
+       char *p;
+       struct smbldap_state *ls;
+       GROUP_MAP gmap;
+       DOM_SID gsid;
+       gid_t domusers_gid = -1;
+       gid_t domadmins_gid = -1;
+       struct samu *samuser;
+       struct passwd *pwd;
+
+       tc = talloc_new(NULL);
+       if (!tc) {
+               d_fprintf(stderr, "Out of Memory!\n");
+               return -1;
+       }
+
+       if ((ldap_bk = talloc_strdup(tc, lp_passdb_backend())) == NULL) {
+               d_fprintf(stderr, "talloc failed\n");
+               talloc_free(tc);
+               return -1;
+       }
+       p = strchr(ldap_bk, ':');
+       if (p) {
+               *p = 0;
+               ldap_uri = talloc_strdup(tc, p+1);
+               trim_char(ldap_uri, ' ', ' ');
+       }
+
+       trim_char(ldap_bk, ' ', ' ');
+               
+       if (strcmp(ldap_bk, "ldapsam") != 0) {
+               d_fprintf(stderr, "Provisioning works only with ldapsam backend\n");
+               goto failed;
+       }
+       
+       if (!lp_parm_bool(-1, "ldapsam", "trusted", False) ||
+           !lp_parm_bool(-1, "ldapsam", "editposix", False)) {
+
+               d_fprintf(stderr, "Provisioning works only if ldapsam:trusted"
+                                 " and ldapsam:editposix are enabled.\n");
+               goto failed;
+       }
+
+       if (!winbind_ping()) {
+               d_fprintf(stderr, "winbind seems not to run. Provisioning "
+                         "LDAP only works when winbind runs.\n");
+               goto failed;
+       }
+
+       if (!NT_STATUS_IS_OK(smbldap_init(tc, ldap_uri, &ls))) {
+               d_fprintf(stderr, "Unable to connect to the LDAP server.\n");
+               goto failed;
+       }
+
+       d_printf("Checking for Domain Users group.\n");
+
+       sid_compose(&gsid, get_global_sam_sid(), DOMAIN_GROUP_RID_USERS);
+
+       if (!pdb_getgrsid(&gmap, gsid)) {
+               LDAPMod **mods = NULL;
+               char *dn;
+               char *uname;
+               char *wname;
+               char *gidstr;
+               char *gtype;
+               int rc;
+
+               d_printf("Adding the Domain Users group.\n");
+
+               /* lets allocate a new groupid for this group */
+               if (!winbind_allocate_gid(&domusers_gid)) {
+                       d_fprintf(stderr, "Unable to allocate a new gid to create Domain Users group!\n");
+                       goto domu_done;
+               }
+
+               uname = talloc_strdup(tc, "domusers");
+               wname = talloc_strdup(tc, "Domain Users");
+               dn = talloc_asprintf(tc, "cn=%s,%s", "domusers", lp_ldap_group_suffix());
+               gidstr = talloc_asprintf(tc, "%d", domusers_gid);
+               gtype = talloc_asprintf(tc, "%d", SID_NAME_DOM_GRP);
+
+               if (!uname || !wname || !dn || !gidstr || !gtype) {
+                       d_fprintf(stderr, "Out of Memory!\n");
+                       goto failed;
+               }
+
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_POSIXGROUP);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", uname);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", wname);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid", sid_string_static(&gsid));
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", gtype);
+
+               talloc_autofree_ldapmod(tc, mods);
+
+               rc = smbldap_add(ls, dn, mods);
+
+               if (rc != LDAP_SUCCESS) {
+                       d_fprintf(stderr, "Failed to add Domain Users group to ldap directory\n");
+               }
+       } else {
+               d_printf("found!\n");
+       }       
+
+domu_done:
+
+       d_printf("Checking for Domain Admins group.\n");
+
+       sid_compose(&gsid, get_global_sam_sid(), DOMAIN_GROUP_RID_ADMINS);
+
+       if (!pdb_getgrsid(&gmap, gsid)) {
+               LDAPMod **mods = NULL;
+               char *dn;
+               char *uname;
+               char *wname;
+               char *gidstr;
+               char *gtype;
+               int rc;
+
+               d_printf("Adding the Domain Admins group.\n");
+
+               /* lets allocate a new groupid for this group */
+               if (!winbind_allocate_gid(&domadmins_gid)) {
+                       d_fprintf(stderr, "Unable to allocate a new gid to create Domain Admins group!\n");
+                       goto doma_done;
+               }
+
+               uname = talloc_strdup(tc, "domadmins");
+               wname = talloc_strdup(tc, "Domain Admins");
+               dn = talloc_asprintf(tc, "cn=%s,%s", "domadmins", lp_ldap_group_suffix());
+               gidstr = talloc_asprintf(tc, "%d", domadmins_gid);
+               gtype = talloc_asprintf(tc, "%d", SID_NAME_DOM_GRP);
+
+               if (!uname || !wname || !dn || !gidstr || !gtype) {
+                       d_fprintf(stderr, "Out of Memory!\n");
+                       goto failed;
+               }
+
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_POSIXGROUP);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", uname);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", wname);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid", sid_string_static(&gsid));
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", gtype);
+
+               talloc_autofree_ldapmod(tc, mods);
+
+               rc = smbldap_add(ls, dn, mods);
+
+               if (rc != LDAP_SUCCESS) {
+                       d_fprintf(stderr, "Failed to add Domain Admins group to ldap directory\n");
+               }
+       } else {
+               d_printf("found!\n");
+       }
+
+doma_done:
+
+       d_printf("Check for Administrator account.\n");
+
+       samuser = samu_new(tc);
+       if (!samuser) {
+               d_fprintf(stderr, "Out of Memory!\n");
+               goto failed;
+       }
+
+       if (!pdb_getsampwnam(samuser, "Administrator")) {
+               LDAPMod **mods = NULL;
+               DOM_SID sid;
+               char *dn;
+               char *name;
+               char *uidstr;
+               char *gidstr;
+               char *shell;
+               char *dir;
+               uid_t uid;
+               int rc;
+               
+               d_printf("Adding the Administrator user.\n");
+
+               if (domadmins_gid == -1) {
+                       d_fprintf(stderr, "Can't create Administrtor user, Domain Admins group not available!\n");
+                       goto done;
+               }
+               if (!winbind_allocate_uid(&uid)) {
+                       d_fprintf(stderr, "Unable to allocate a new uid to create the Administrator user!\n");
+                       goto done;
+               }
+               name = talloc_strdup(tc, "Administrator");
+               dn = talloc_asprintf(tc, "uid=Administrator,%s", lp_ldap_user_suffix());
+               uidstr = talloc_asprintf(tc, "%d", uid);
+               gidstr = talloc_asprintf(tc, "%d", domadmins_gid);
+               dir = talloc_sub_specified(tc, lp_template_homedir(),
+                                               "Administrator",
+                                               get_global_sam_name(),
+                                               uid, domadmins_gid);
+               shell = talloc_sub_specified(tc, lp_template_shell(),
+                                               "Administrator",
+                                               get_global_sam_name(),
+                                               uid, domadmins_gid);
+
+               if (!name || !dn || !uidstr || !gidstr || !dir || !shell) {
+                       d_fprintf(stderr, "Out of Memory!\n");
+                       goto failed;
+               }
+
+               sid_compose(&sid, get_global_sam_sid(), DOMAIN_USER_RID_ADMIN);
+
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_ACCOUNT);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXACCOUNT);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "uid", name);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", name);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", name);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "uidNumber", uidstr);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "homeDirectory", dir);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "loginShell", shell);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSID", sid_string_static(&sid));
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaAcctFlags",
+                               pdb_encode_acct_ctrl(ACB_NORMAL|ACB_DISABLED,
+                               NEW_PW_FORMAT_SPACE_PADDED_LEN));
+
+               talloc_autofree_ldapmod(tc, mods);
+
+               rc = smbldap_add(ls, dn, mods);
+
+               if (rc != LDAP_SUCCESS) {
+                       d_fprintf(stderr, "Failed to add Administrator user to ldap directory\n");
+               }
+       } else {
+               d_printf("found!\n");
+       }
+
+       d_printf("Checking for Guest user.\n");
+
+       samuser = samu_new(tc);
+       if (!samuser) {
+               d_fprintf(stderr, "Out of Memory!\n");
+               goto failed;
+       }
+
+       if (!pdb_getsampwnam(samuser, lp_guestaccount())) {
+               LDAPMod **mods = NULL;
+               DOM_SID sid;
+               char *dn;
+               char *uidstr;
+               char *gidstr;
+               int rc;
+               
+               d_printf("Adding the Guest user.\n");
+
+               pwd = getpwnam_alloc(tc, lp_guestaccount());
+
+               if (!pwd) {
+                       if (domusers_gid == -1) {
+                               d_fprintf(stderr, "Can't create Guest user, Domain Users group not available!\n");
+                               goto done;
+                       }
+                       if ((pwd = talloc(tc, struct passwd)) == NULL) {
+                               d_fprintf(stderr, "talloc failed\n");
+                               goto done;
+                       }
+                       pwd->pw_name = talloc_strdup(pwd, lp_guestaccount());
+                       if (!winbind_allocate_uid(&(pwd->pw_uid))) {
+                               d_fprintf(stderr, "Unable to allocate a new uid to create the Guest user!\n");
+                               goto done;
+                       }
+                       pwd->pw_gid = domusers_gid;
+                       pwd->pw_dir = talloc_strdup(tc, "/");
+                       pwd->pw_shell = talloc_strdup(tc, "/bin/false");
+                       if (!pwd->pw_dir || !pwd->pw_shell) {
+                               d_fprintf(stderr, "Out of Memory!\n");
+                               goto failed;
+                       }
+               }
+
+               sid_compose(&sid, get_global_sam_sid(), DOMAIN_USER_RID_GUEST);
+
+               dn = talloc_asprintf(tc, "uid=%s,%s", pwd->pw_name, lp_ldap_user_suffix ());
+               uidstr = talloc_asprintf(tc, "%d", pwd->pw_uid);
+               gidstr = talloc_asprintf(tc, "%d", pwd->pw_gid);
+               if (!dn || !uidstr || !gidstr) {
+                       d_fprintf(stderr, "Out of Memory!\n");
+                       goto failed;
+               }
+
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_ACCOUNT);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXACCOUNT);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "uid", pwd->pw_name);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", pwd->pw_name);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", pwd->pw_name);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "uidNumber", uidstr);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "homeDirectory", pwd->pw_dir);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "loginShell", pwd->pw_shell);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSID", sid_string_static(&sid));
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaAcctFlags",
+                               pdb_encode_acct_ctrl(ACB_NORMAL|ACB_DISABLED,
+                               NEW_PW_FORMAT_SPACE_PADDED_LEN));
+
+               talloc_autofree_ldapmod(tc, mods);
+
+               rc = smbldap_add(ls, dn, mods);
+
+               if (rc != LDAP_SUCCESS) {
+                       d_fprintf(stderr, "Failed to add Guest user to ldap directory\n");
+               }
+       } else {
+               d_printf("found!\n");
+       }
+
+       d_printf("Checking Guest's group.\n");
+
+       pwd = getpwnam_alloc(NULL, lp_guestaccount());
+       if (!pwd) {
+               d_fprintf(stderr, "Failed to find just created Guest account!\n"
+                                 "   Is nssswitch properly configured?!\n");
+               goto failed;
+       }
+
+       if (pwd->pw_gid == domusers_gid) {
+               d_printf("found!\n");
+               goto done;
+       }
+
+       if (!pdb_getgrgid(&gmap, pwd->pw_gid)) {
+               LDAPMod **mods = NULL;
+               char *dn;
+               char *uname;
+               char *wname;
+               char *gidstr;
+               char *gtype;
+               int rc;
+
+               d_printf("Adding the Domain Guests group.\n");
+
+               uname = talloc_strdup(tc, "domguests");
+               wname = talloc_strdup(tc, "Domain Guests");
+               dn = talloc_asprintf(tc, "cn=%s,%s", "domguests", lp_ldap_group_suffix());
+               gidstr = talloc_asprintf(tc, "%d", pwd->pw_gid);
+               gtype = talloc_asprintf(tc, "%d", SID_NAME_DOM_GRP);
+
+               if (!uname || !wname || !dn || !gidstr || !gtype) {
+                       d_fprintf(stderr, "Out of Memory!\n");
+                       goto failed;
+               }
+
+               sid_compose(&gsid, get_global_sam_sid(), DOMAIN_GROUP_RID_GUESTS);
+
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_POSIXGROUP);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "cn", uname);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", wname);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "gidNumber", gidstr);
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid", sid_string_static(&gsid));
+               smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", gtype);
+
+               talloc_autofree_ldapmod(tc, mods);
+
+               rc = smbldap_add(ls, dn, mods);
+
+               if (rc != LDAP_SUCCESS) {
+                       d_fprintf(stderr, "Failed to add Domain Guests group to ldap directory\n");
+               }
+       } else {
+               d_printf("found!\n");
+       }
+
+
+done:
+       talloc_free(tc);
+       return 0;
+
+failed:
+       talloc_free(tc);
+       return -1;
+}
+
+#endif
+
 /***********************************************************
  migrated functionality from smbgroupedit
  **********************************************************/
 int net_sam(int argc, const char **argv)
 {
        struct functable2 func[] = {
+               { "createbuiltingroup", net_sam_createbuiltingroup,
+                 "Create a new BUILTIN group" },
                { "createlocalgroup", net_sam_createlocalgroup,
                  "Create a new local group" },
                { "mapunixgroup", net_sam_mapunixgroup,
@@ -769,6 +1232,10 @@ int net_sam(int argc, const char **argv)
                  "Show details of a SAM entry" },
                { "set", net_sam_set,
                  "Set details of a SAM account" },
+#ifdef HAVE_LDAP
+               { "provision", net_sam_provision,
+                 "Provision a clean User Database" },
+#endif
                { NULL, NULL, NULL }
        };