s3-net: add IPA provision
[mat/samba.git] / source3 / utils / net_sam.c
index 95405f3e095a54d1d700a9a57569956927d6aa32..4754fb0f34327ba106d212a8faaaa69a74c8f5eb 100644 (file)
 
 
 #include "includes.h"
+#include "system/passwd.h"
 #include "utils/net.h"
+#include "../librpc/gen_ndr/samr.h"
+#include "smbldap.h"
+#include "../libcli/security/security.h"
+#include "lib/winbind_util.h"
+#include "passdb.h"
+#include "lib/privileges.h"
 
 /*
  * Set a user's data
@@ -31,13 +38,14 @@ static int net_sam_userset(struct net_context *c, int argc, const char **argv,
                                      enum pdb_value_state))
 {
        struct samu *sam_acct = NULL;
-       DOM_SID sid;
+       struct dom_sid sid;
        enum lsa_SidType type;
        const char *dom, *name;
        NTSTATUS status;
 
        if (argc != 2 || c->display_usage) {
-               d_fprintf(stderr, _("usage: net sam set %s <user> <value>\n"),
+               d_fprintf(stderr, "%s\n", _("Usage:"));
+               d_fprintf(stderr, _("net sam set %s <user> <value>\n"),
                          field);
                return -1;
        }
@@ -133,16 +141,17 @@ static int net_sam_set_userflag(struct net_context *c, int argc,
                                uint16 flag)
 {
        struct samu *sam_acct = NULL;
-       DOM_SID sid;
+       struct dom_sid sid;
        enum lsa_SidType type;
        const char *dom, *name;
        NTSTATUS status;
-       uint16 acct_flags;
+       uint32_t acct_flags;
 
        if ((argc != 2) || c->display_usage ||
            (!strequal(argv[1], "yes") &&
             !strequal(argv[1], "no"))) {
-               d_fprintf(stderr, _("usage: net sam set %s <user> [yes|no]\n"),
+               d_fprintf(stderr, "%s\n", _("Usage:"));
+               d_fprintf(stderr, _("net sam set %s <user> [yes|no]\n"),
                          field);
                return -1;
        }
@@ -225,7 +234,7 @@ static int net_sam_set_pwdmustchangenow(struct net_context *c, int argc,
                                        const char **argv)
 {
        struct samu *sam_acct = NULL;
-       DOM_SID sid;
+       struct dom_sid sid;
        enum lsa_SidType type;
        const char *dom, *name;
        NTSTATUS status;
@@ -233,9 +242,9 @@ static int net_sam_set_pwdmustchangenow(struct net_context *c, int argc,
        if ((argc != 2) || c->display_usage ||
            (!strequal(argv[1], "yes") &&
             !strequal(argv[1], "no"))) {
-               d_fprintf(stderr,
-                         _("usage: net sam set pwdmustchangenow <user> "
-                           "[yes|no]\n"));
+               d_fprintf(stderr, "%s\n%s",
+                         _("Usage:"),
+                         _("net sam set pwdmustchangenow <user> [yes|no]\n"));
                return -1;
        }
 
@@ -291,14 +300,15 @@ static int net_sam_set_comment(struct net_context *c, int argc,
                               const char **argv)
 {
        GROUP_MAP map;
-       DOM_SID sid;
+       struct dom_sid sid;
        enum lsa_SidType type;
        const char *dom, *name;
        NTSTATUS status;
 
        if (argc != 2 || c->display_usage) {
-               d_fprintf(stderr, _("usage: net sam set comment <name> "
-                         "<comment>\n"));
+               d_fprintf(stderr, "%s\n%s",
+                         _("Usage:"),
+                         _("net sam set comment <name> <comment>\n"));
                return -1;
        }
 
@@ -461,8 +471,9 @@ static int net_sam_policy_set(struct net_context *c, int argc, const char **argv
        char *endptr;
 
         if (argc != 2 || c->display_usage) {
-                d_fprintf(stderr, _("usage: net sam policy set "
-                         "\"<account policy>\" <value> \n"));
+                d_fprintf(stderr, "%s\n%s",
+                         _("Usage:"),
+                         _("net sam policy set \"<account policy>\" <value>\n"));
                 return -1;
         }
 
@@ -527,8 +538,9 @@ static int net_sam_policy_show(struct net_context *c, int argc, const char **arg
         enum pdb_policy_type field;
 
         if (argc != 1 || c->display_usage) {
-                d_fprintf(stderr, _("usage: net sam policy show"
-                         " \"<account policy>\" \n"));
+                d_fprintf(stderr, "%s\n%s",
+                         _("Usage:"),
+                         _("net sam policy show \"<account policy>\"\n"));
                 return -1;
         }
 
@@ -572,9 +584,11 @@ static int net_sam_policy_list(struct net_context *c, int argc, const char **arg
        int i;
 
        if (c->display_usage) {
-               d_printf(_("Usage:\n"
+               d_printf(  "%s\n"
                           "net sam policy list\n"
-                          "    List account policies\n"));
+                          "    %s\n",
+                        _("Usage:"),
+                        _("List account policies"));
                return 0;
        }
 
@@ -623,35 +637,36 @@ static int net_sam_policy(struct net_context *c, int argc, const char **argv)
         return net_run_function(c, argc, argv, "net sam policy", func);
 }
 
-extern PRIVS privs[];
-
 static int net_sam_rights_list(struct net_context *c, int argc,
                               const char **argv)
 {
-       SE_PRIV mask;
+       enum sec_privilege privilege;
 
        if (argc > 1 || c->display_usage) {
-               d_fprintf(stderr,
-                         _("usage: net sam rights list [privilege name]\n"));
+               d_fprintf(stderr, "%s\n%s",
+                         _("Usage:"),
+                         _("net sam rights list [privilege name]\n"));
                return -1;
        }
 
        if (argc == 0) {
                int i;
-               int num = count_all_privileges();
+               int num = num_privileges_in_short_list();
 
                for (i=0; i<num; i++) {
-                       d_printf("%s\n", privs[i].name);
+                       d_printf("%s\n", sec_privilege_name_from_index(i));
                }
                return 0;
        }
 
-       if (se_priv_from_name(argv[0], &mask)) {
-               DOM_SID *sids;
+       privilege = sec_privilege_id(argv[0]);
+
+       if (privilege != SEC_PRIV_INVALID) {
+               struct dom_sid *sids;
                int i, num_sids;
                NTSTATUS status;
 
-               status = privilege_enum_sids(&mask, talloc_tos(),
+               status = privilege_enum_sids(privilege, talloc_tos(),
                                             &sids, &num_sids);
                if (!NT_STATUS_IS_OK(status)) {
                        d_fprintf(stderr, _("Could not list rights: %s\n"),
@@ -680,15 +695,15 @@ static int net_sam_rights_list(struct net_context *c, int argc,
 static int net_sam_rights_grant(struct net_context *c, int argc,
                                const char **argv)
 {
-       DOM_SID sid;
+       struct dom_sid sid;
        enum lsa_SidType type;
        const char *dom, *name;
-       SE_PRIV mask;
        int i;
 
        if (argc < 2 || c->display_usage) {
-               d_fprintf(stderr, _("usage: net sam rights grant <name> "
-                       "<rights> ...\n"));
+               d_fprintf(stderr, "%s\n%s",
+                         _("Usage:"),
+                         _("net sam rights grant <name> <rights> ...\n"));
                return -1;
        }
 
@@ -699,12 +714,13 @@ static int net_sam_rights_grant(struct net_context *c, int argc,
        }
 
        for (i=1; i < argc; i++) {
-               if (!se_priv_from_name(argv[i], &mask)) {
+               enum sec_privilege privilege = sec_privilege_id(argv[i]);
+               if (privilege == SEC_PRIV_INVALID) {
                        d_fprintf(stderr, _("%s unknown\n"), argv[i]);
                        return -1;
                }
 
-               if (!grant_privilege(&sid, &mask)) {
+               if (!grant_privilege_by_name(&sid, argv[i])) {
                        d_fprintf(stderr, _("Could not grant privilege\n"));
                        return -1;
                }
@@ -718,15 +734,15 @@ static int net_sam_rights_grant(struct net_context *c, int argc,
 static int net_sam_rights_revoke(struct net_context *c, int argc,
                                const char **argv)
 {
-       DOM_SID sid;
+       struct dom_sid sid;
        enum lsa_SidType type;
        const char *dom, *name;
-       SE_PRIV mask;
        int i;
 
        if (argc < 2 || c->display_usage) {
-               d_fprintf(stderr, _("usage: net sam rights revoke <name> "
-                       "<rights>\n"));
+               d_fprintf(stderr, "%s\n%s",
+                         _("Usage:"),
+                         _("net sam rights revoke <name> <rights>\n"));
                return -1;
        }
 
@@ -737,13 +753,13 @@ static int net_sam_rights_revoke(struct net_context *c, int argc,
        }
 
        for (i=1; i < argc; i++) {
-
-               if (!se_priv_from_name(argv[i], &mask)) {
+               enum sec_privilege privilege = sec_privilege_id(argv[i]);
+               if (privilege == SEC_PRIV_INVALID) {
                        d_fprintf(stderr, _("%s unknown\n"), argv[i]);
                        return -1;
                }
 
-               if (!revoke_privilege(&sid, &mask)) {
+               if (!revoke_privilege_by_name(&sid, argv[i])) {
                        d_fprintf(stderr, _("Could not revoke privilege\n"));
                        return -1;
                }
@@ -852,7 +868,9 @@ static int net_sam_mapunixgroup(struct net_context *c, int argc, const char **ar
        struct group *grp;
 
        if (argc != 1 || c->display_usage) {
-               d_fprintf(stderr, _("usage: net sam mapunixgroup <name>\n"));
+               d_fprintf(stderr, "%s\n%s",
+                         _("Usage:"),
+                         _("net sam mapunixgroup <name>\n"));
                return -1;
        }
 
@@ -882,10 +900,9 @@ static int net_sam_mapunixgroup(struct net_context *c, int argc, const char **ar
 
 static NTSTATUS unmap_unix_group(const struct group *grp, GROUP_MAP *pmap)
 {
-        NTSTATUS status;
         GROUP_MAP map;
         const char *grpname;
-        DOM_SID dom_sid;
+        struct dom_sid dom_sid;
 
         map.gid = grp->gr_gid;
         grpname = grp->gr_name;
@@ -902,9 +919,7 @@ static NTSTATUS unmap_unix_group(const struct group *grp, GROUP_MAP *pmap)
                 return NT_STATUS_UNSUCCESSFUL;
         }
 
-        status = pdb_delete_group_mapping_entry(dom_sid);
-
-        return status;
+        return pdb_delete_group_mapping_entry(dom_sid);
 }
 
 static int net_sam_unmapunixgroup(struct net_context *c, int argc, const char **argv)
@@ -914,7 +929,9 @@ static int net_sam_unmapunixgroup(struct net_context *c, int argc, const char **
        struct group *grp;
 
        if (argc != 1 || c->display_usage) {
-               d_fprintf(stderr, _("usage: net sam unmapunixgroup <name>\n"));
+               d_fprintf(stderr, "%s\n%s",
+                         _("Usage:"),
+                         _("net sam unmapunixgroup <name>\n"));
                return -1;
        }
 
@@ -949,8 +966,9 @@ static int net_sam_createdomaingroup(struct net_context *c, int argc,
        uint32 rid;
 
        if (argc != 1 || c->display_usage) {
-               d_fprintf(stderr,
-                         _("usage: net sam createdomaingroup <name>\n"));
+               d_fprintf(stderr, "%s\n%s",
+                         _("Usage:"),
+                         _("net sam createdomaingroup <name>\n"));
                return -1;
        }
 
@@ -974,14 +992,16 @@ static int net_sam_createdomaingroup(struct net_context *c, int argc,
 static int net_sam_deletedomaingroup(struct net_context *c, int argc,
                                     const char **argv)
 {
-       DOM_SID sid;
+       struct dom_sid sid;
        uint32_t rid;
         enum lsa_SidType type;
         const char *dom, *name;
        NTSTATUS status;
 
        if (argc != 1 || c->display_usage) {
-               d_fprintf(stderr,_("usage: net sam deletelocalgroup <name>\n"));
+               d_fprintf(stderr, "%s\n%s",
+                         _("Usage:"),
+                         _("net sam deletelocalgroup <name>\n"));
                return -1;
        }
 
@@ -1022,7 +1042,9 @@ static int net_sam_createlocalgroup(struct net_context *c, int argc, const char
        uint32 rid;
 
        if (argc != 1 || c->display_usage) {
-               d_fprintf(stderr,_("usage: net sam createlocalgroup <name>\n"));
+               d_fprintf(stderr, "%s\n%s",
+                         _("Usage:"),
+                         _("net sam createlocalgroup <name>\n"));
                return -1;
        }
 
@@ -1051,13 +1073,15 @@ static int net_sam_createlocalgroup(struct net_context *c, int argc, const char
 
 static int net_sam_deletelocalgroup(struct net_context *c, int argc, const char **argv)
 {
-       DOM_SID sid;
+       struct dom_sid sid;
         enum lsa_SidType type;
         const char *dom, *name;
        NTSTATUS status;
 
        if (argc != 1 || c->display_usage) {
-               d_fprintf(stderr,_("usage: net sam deletelocalgroup <name>\n"));
+               d_fprintf(stderr, "%s\n%s",
+                         _("Usage:"),
+                         _("net sam deletelocalgroup <name>\n"));
                return -1;
        }
 
@@ -1096,11 +1120,12 @@ static int net_sam_createbuiltingroup(struct net_context *c, int argc, const cha
        uint32 rid;
        enum lsa_SidType type;
        fstring groupname;
-       DOM_SID sid;
+       struct dom_sid sid;
 
        if (argc != 1 || c->display_usage) {
-               d_fprintf(stderr,
-                         _("usage: net sam createbuiltingroup <name>\n"));
+               d_fprintf(stderr, "%s\n%s",
+                         _("Usage:"),
+                         _("net sam createbuiltingroup <name>\n"));
                return -1;
        }
 
@@ -1147,12 +1172,14 @@ static int net_sam_createbuiltingroup(struct net_context *c, int argc, const cha
 static int net_sam_addmem(struct net_context *c, int argc, const char **argv)
 {
        const char *groupdomain, *groupname, *memberdomain, *membername;
-       DOM_SID group, member;
+       struct dom_sid group, member;
        enum lsa_SidType grouptype, membertype;
        NTSTATUS status;
 
        if (argc != 2 || c->display_usage) {
-               d_fprintf(stderr,_("usage: net sam addmem <group> <member>\n"));
+               d_fprintf(stderr, "%s\n%s",
+                         _("Usage:"),
+                         _("net sam addmem <group> <member>\n"));
                return -1;
        }
 
@@ -1234,12 +1261,14 @@ static int net_sam_delmem(struct net_context *c, int argc, const char **argv)
        const char *groupdomain, *groupname;
        const char *memberdomain = NULL;
        const char *membername = NULL;
-       DOM_SID group, member;
+       struct dom_sid group, member;
        enum lsa_SidType grouptype;
        NTSTATUS status;
 
        if (argc != 2 || c->display_usage) {
-               d_fprintf(stderr,_("usage: net sam delmem <group> <member>\n"));
+               d_fprintf(stderr,"%s\n%s",
+                         _("Usage:"),
+                         _("net sam delmem <group> <member>\n"));
                return -1;
        }
 
@@ -1304,14 +1333,16 @@ static int net_sam_delmem(struct net_context *c, int argc, const char **argv)
 static int net_sam_listmem(struct net_context *c, int argc, const char **argv)
 {
        const char *groupdomain, *groupname;
-       DOM_SID group;
-       DOM_SID *members = NULL;
+       struct dom_sid group;
+       struct dom_sid *members = NULL;
        size_t i, num_members = 0;
        enum lsa_SidType grouptype;
        NTSTATUS status;
 
        if (argc != 1 || c->display_usage) {
-               d_fprintf(stderr, _("usage: net sam listmem <group>\n"));
+               d_fprintf(stderr, "%s\n%s",
+                         _("Usage:"),
+                         _("net sam listmem <group>\n"));
                return -1;
        }
 
@@ -1385,7 +1416,8 @@ static int net_sam_do_list(struct net_context *c, int argc, const char **argv,
 
        if ((argc > 1) || c->display_usage ||
            ((argc == 1) && !strequal(argv[0], "verbose"))) {
-               d_fprintf(stderr,_("usage: net sam list %s [verbose]\n"), what);
+               d_fprintf(stderr, "%s\n", _("Usage:"));
+               d_fprintf(stderr, _("net sam list %s [verbose]\n"), what);
                return -1;
        }
 
@@ -1513,12 +1545,14 @@ static int net_sam_list(struct net_context *c, int argc, const char **argv)
 
 static int net_sam_show(struct net_context *c, int argc, const char **argv)
 {
-       DOM_SID sid;
+       struct dom_sid sid;
        enum lsa_SidType type;
        const char *dom, *name;
 
        if (argc != 1 || c->display_usage) {
-               d_fprintf(stderr, _("usage: net sam show <name>\n"));
+               d_fprintf(stderr, "%s\n%s",
+                         _("Usage:"),
+                         _("net sam show <name>\n"));
                return -1;
        }
 
@@ -1549,17 +1583,19 @@ static int net_sam_provision(struct net_context *c, int argc, const char **argv)
        char *p;
        struct smbldap_state *ls;
        GROUP_MAP gmap;
-       DOM_SID gsid;
+       struct dom_sid gsid;
        gid_t domusers_gid = -1;
        gid_t domadmins_gid = -1;
        struct samu *samuser;
        struct passwd *pwd;
+       bool is_ipa = false;
 
        if (c->display_usage) {
-               d_printf(_("Usage:\n"
+               d_printf(  "%s\n"
                           "net sam provision\n"
-                           "    Init an LDAP tree with default "
-                           "users/groups\n"));
+                           "    %s\n",
+                         _("Usage:"),
+                         _("Init an LDAP tree with default users/groups"));
                return 0;
        }
 
@@ -1583,7 +1619,11 @@ static int net_sam_provision(struct net_context *c, int argc, const char **argv)
 
        trim_char(ldap_bk, ' ', ' ');
 
-       if (strcmp(ldap_bk, "ldapsam") != 0) {
+       if (strcmp(ldap_bk, "IPA_ldapsam") == 0 ) {
+               is_ipa = true;
+       }
+
+       if (strcmp(ldap_bk, "ldapsam") != 0 && !is_ipa ) {
                d_fprintf(stderr,
                          _("Provisioning works only with ldapsam backend\n"));
                goto failed;
@@ -1597,7 +1637,7 @@ static int net_sam_provision(struct net_context *c, int argc, const char **argv)
                goto failed;
        }
 
-       if (!winbind_ping()) {
+       if (!is_ipa && !winbind_ping()) {
                d_fprintf(stderr, _("winbind seems not to run. Provisioning "
                            "LDAP only works when winbind runs.\n"));
                goto failed;
@@ -1610,7 +1650,7 @@ static int net_sam_provision(struct net_context *c, int argc, const char **argv)
 
        d_printf(_("Checking for Domain Users group.\n"));
 
-       sid_compose(&gsid, get_global_sam_sid(), DOMAIN_GROUP_RID_USERS);
+       sid_compose(&gsid, get_global_sam_sid(), DOMAIN_RID_USERS);
 
        if (!pdb_getgrsid(&gmap, gsid)) {
                LDAPMod **mods = NULL;
@@ -1624,10 +1664,14 @@ static int net_sam_provision(struct net_context *c, int argc, const char **argv)
                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;
+               if (is_ipa) {
+                       domusers_gid = 999;
+               } else {
+                       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");
@@ -1643,6 +1687,11 @@ static int net_sam_provision(struct net_context *c, int argc, const char **argv)
 
                smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXGROUP);
                smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
+               if (is_ipa) {
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "groupofnames");
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "nestedgroup");
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "ipausergroup");
+               }
                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);
@@ -1658,6 +1707,16 @@ static int net_sam_provision(struct net_context *c, int argc, const char **argv)
                        d_fprintf(stderr, _("Failed to add Domain Users group "
                                            "to ldap directory\n"));
                }
+
+               if (is_ipa) {
+                       if (!pdb_getgrsid(&gmap, gsid)) {
+                               d_fprintf(stderr, _("Failed to read just "
+                                                   "created domain group.\n"));
+                               goto failed;
+                       } else {
+                               domusers_gid = gmap.gid;
+                       }
+               }
        } else {
                domusers_gid = gmap.gid;
                d_printf(_("found!\n"));
@@ -1667,7 +1726,7 @@ domu_done:
 
        d_printf(_("Checking for Domain Admins group.\n"));
 
-       sid_compose(&gsid, get_global_sam_sid(), DOMAIN_GROUP_RID_ADMINS);
+       sid_compose(&gsid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
 
        if (!pdb_getgrsid(&gmap, gsid)) {
                LDAPMod **mods = NULL;
@@ -1681,10 +1740,14 @@ domu_done:
                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;
+               if (is_ipa) {
+                       domadmins_gid = 999;
+               } else {
+                       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");
@@ -1700,6 +1763,11 @@ domu_done:
 
                smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXGROUP);
                smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
+               if (is_ipa) {
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "groupofnames");
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "nestedgroup");
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "ipausergroup");
+               }
                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);
@@ -1715,6 +1783,16 @@ domu_done:
                        d_fprintf(stderr, _("Failed to add Domain Admins group "
                                            "to ldap directory\n"));
                }
+
+               if (is_ipa) {
+                       if (!pdb_getgrsid(&gmap, gsid)) {
+                               d_fprintf(stderr, _("Failed to read just "
+                                                   "created domain group.\n"));
+                               goto failed;
+                       } else {
+                               domadmins_gid = gmap.gid;
+                       }
+               }
        } else {
                domadmins_gid = gmap.gid;
                d_printf(_("found!\n"));
@@ -1732,13 +1810,14 @@ doma_done:
 
        if (!pdb_getsampwnam(samuser, "Administrator")) {
                LDAPMod **mods = NULL;
-               DOM_SID sid;
+               struct dom_sid sid;
                char *dn;
                char *name;
                char *uidstr;
                char *gidstr;
                char *shell;
                char *dir;
+               char *princ;
                uid_t uid;
                int rc;
 
@@ -1750,12 +1829,18 @@ doma_done:
                                    "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;
+
+               if (is_ipa) {
+                       uid = 999;
+               } else {
+                       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, "%u", (unsigned int)uid);
@@ -1774,11 +1859,26 @@ doma_done:
                        goto failed;
                }
 
-               sid_compose(&sid, get_global_sam_sid(), DOMAIN_USER_RID_ADMIN);
+               sid_compose(&sid, get_global_sam_sid(), DOMAIN_RID_ADMINISTRATOR);
 
                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);
+               if (is_ipa) {
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "person");
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "organizationalperson");
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "inetorgperson");
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "inetuser");
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "krbprincipalaux");
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "krbticketpolicyaux");
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "sn", name);
+                       princ = talloc_asprintf(tc, "%s@%s", name, lp_realm());
+                       if (!princ) {
+                               d_fprintf(stderr, _("Out of Memory!\n"));
+                               goto failed;
+                       }
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "krbPrincipalName", princ);
+               }
                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);
@@ -1800,6 +1900,14 @@ doma_done:
                        d_fprintf(stderr, _("Failed to add Administrator user "
                                            "to ldap directory\n"));
                }
+
+               if (is_ipa) {
+                       if (!pdb_getsampwnam(samuser, "Administrator")) {
+                               d_fprintf(stderr, _("Failed to read just "
+                                                   "created user.\n"));
+                               goto failed;
+                       }
+               }
        } else {
                d_printf(_("found!\n"));
        }
@@ -1814,7 +1922,7 @@ doma_done:
 
        if (!pdb_getsampwnam(samuser, lp_guestaccount())) {
                LDAPMod **mods = NULL;
-               DOM_SID sid;
+               struct dom_sid sid;
                char *dn;
                char *uidstr;
                char *gidstr;
@@ -1822,7 +1930,9 @@ doma_done:
 
                d_printf(_("Adding the Guest user.\n"));
 
-               pwd = getpwnam_alloc(tc, lp_guestaccount());
+               sid_compose(&sid, get_global_sam_sid(), DOMAIN_RID_GUEST);
+
+               pwd = Get_Pwnam_alloc(tc, lp_guestaccount());
 
                if (!pwd) {
                        if (domusers_gid == -1) {
@@ -1836,11 +1946,16 @@ doma_done:
                                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;
+
+                       if (is_ipa) {
+                               pwd->pw_uid = 999;
+                       } else {
+                               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, "/");
@@ -1851,8 +1966,6 @@ doma_done:
                        }
                }
 
-               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, "%u", (unsigned int)pwd->pw_uid);
                gidstr = talloc_asprintf(tc, "%u", (unsigned int)pwd->pw_gid);
@@ -1864,6 +1977,15 @@ doma_done:
                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);
+               if (is_ipa) {
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "person");
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "organizationalperson");
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "inetorgperson");
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "inetuser");
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "krbprincipalaux");
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "krbticketpolicyaux");
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "sn", pwd->pw_name);
+               }
                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);
@@ -1889,13 +2011,21 @@ doma_done:
                        d_fprintf(stderr, _("Failed to add Guest user to "
                                            "ldap directory\n"));
                }
+
+               if (is_ipa) {
+                       if (!pdb_getsampwnam(samuser, lp_guestaccount())) {
+                               d_fprintf(stderr, _("Failed to read just "
+                                                   "created user.\n"));
+                               goto failed;
+                       }
+               }
        } else {
                d_printf(_("found!\n"));
        }
 
        d_printf(_("Checking Guest's group.\n"));
 
-       pwd = getpwnam_alloc(talloc_autofree_context(), lp_guestaccount());
+       pwd = Get_Pwnam_alloc(tc, lp_guestaccount());
        if (!pwd) {
                d_fprintf(stderr,
                          _("Failed to find just created Guest account!\n"
@@ -1930,10 +2060,15 @@ doma_done:
                        goto failed;
                }
 
-               sid_compose(&gsid, get_global_sam_sid(), DOMAIN_GROUP_RID_GUESTS);
+               sid_compose(&gsid, get_global_sam_sid(), DOMAIN_RID_GUESTS);
 
                smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_POSIXGROUP);
                smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP);
+               if (is_ipa) {
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "groupofnames");
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "nestedgroup");
+                       smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "ipausergroup");
+               }
                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);