From 705d8118081784e9907648fd1daaaa5ec0285972 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 5 Mar 2006 17:49:30 +0000 Subject: [PATCH] r13843: Merge in net sam provision and some pdb_ldap fixes --- source/passdb/pdb_ldap.c | 212 ++++++++++++++++---------- source/utils/net_sam.c | 386 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 516 insertions(+), 82 deletions(-) diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c index 0c7efd3fb97..1fe5212d57a 100644 --- a/source/passdb/pdb_ldap.c +++ b/source/passdb/pdb_ldap.c @@ -1970,7 +1970,7 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, struct s num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result); if (num_result > 1) { - DEBUG (0, ("ldapsam_add_sam_account: More than one user with that uid exists: bailing out!\n")); + DEBUG (0, ("ldapsam_add_sam_account: More than one user with specified Sid exists: bailing out!\n")); TALLOC_FREE( attr_list ); ldap_msgfree(result); return NT_STATUS_UNSUCCESSFUL; @@ -2326,9 +2326,11 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods, *p_num_members = 0; filter = talloc_asprintf(mem_ctx, - "(&(objectClass=sambaGroupMapping)" - "(objectClass=posixGroup)" + "(&(objectClass=%s)" + "(objectClass=%s)" "(sambaSID=%s))", + LDAP_OBJ_POSIXGROUP, + LDAP_OBJ_GROUPMAP, sid_string_static(group)); rc = smbldap_search(conn, lp_ldap_group_suffix(), @@ -2369,7 +2371,7 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods, if (values) { - filter = talloc_strdup(mem_ctx, "(&(objectClass=sambaSamAccount)(|"); + filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(|", LDAP_OBJ_SAMBAACCOUNT); if (filter == NULL) { ret = NT_STATUS_NO_MEMORY; goto done; @@ -2437,8 +2439,10 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods, } filter = talloc_asprintf(mem_ctx, - "(&(objectClass=sambaSamAccount)" - "(gidNumber=%s))", gidstr); + "(&(objectClass=%s)" + "(gidNumber=%s))", + LDAP_OBJ_SAMBASAMACCOUNT, + gidstr); rc = smbldap_search(conn, lp_ldap_user_suffix(), LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0, @@ -2489,39 +2493,74 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)methods->private_data; struct smbldap_state *conn = ldap_state->smbldap_state; - pstring filter; + char *filter; const char *attrs[] = { "gidNumber", "sambaSID", NULL }; char *escape_name; - int rc; - LDAPMessage *msg = NULL; + int rc, count; + LDAPMessage *result = NULL; LDAPMessage *entry; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; size_t num_sids, num_gids; - gid_t primary_gid; + char *gidstr; + gid_t primary_gid = -1; *pp_sids = NULL; num_sids = 0; - if (!sid_to_gid(pdb_get_group_sid(user), &primary_gid)) { - DEBUG(1, ("sid_to_gid failed for user's primary group\n")); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - escape_name = escape_ldap_string_alloc(pdb_get_username(user)); - if (escape_name == NULL) return NT_STATUS_NO_MEMORY; - pstr_sprintf(filter, "(&(objectClass=posixGroup)" - "(|(memberUid=%s)(gidNumber=%d)))", - escape_name, primary_gid); + /* retrieve the users primary gid */ + filter = talloc_asprintf(mem_ctx, + "(&(objectClass=%s)(uid=%s))", + LDAP_OBJ_SAMBASAMACCOUNT, + escape_name); + + rc = smbldap_search(conn, lp_ldap_user_suffix(), + LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result); + + if (rc != LDAP_SUCCESS) + goto done; + + talloc_autofree_ldapmsg(mem_ctx, result); + + count = ldap_count_entries(priv2ld(ldap_state), result); + + switch (count) { + case 0: + DEBUG(1, ("User account [%s] not found!\n", pdb_get_username(user))); + ret = NT_STATUS_NO_SUCH_USER; + goto done; + case 1: + entry = ldap_first_entry(priv2ld(ldap_state), result); + + gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", mem_ctx); + if (!gidstr) { + DEBUG (1, ("Unable to find the member's gid!\n")); + ret = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto done; + } + primary_gid = strtoul(gidstr, NULL, 10); + break; + default: + DEBUG(1, ("found more than one accoutn with the same user name ?!\n")); + ret = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto done; + } + + filter = talloc_asprintf(mem_ctx, + "(&(objectClass=%s)(|(memberUid=%s)(gidNumber=%d)))", + LDAP_OBJ_POSIXGROUP, escape_name, primary_gid); rc = smbldap_search(conn, lp_ldap_group_suffix(), - LDAP_SCOPE_SUBTREE, filter, attrs, 0, &msg); + LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result); if (rc != LDAP_SUCCESS) goto done; + talloc_autofree_ldapmsg(mem_ctx, result); + num_gids = 0; *pp_gids = NULL; @@ -2536,7 +2575,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, add_sid_to_array_unique(mem_ctx, &global_sid_NULL, pp_sids, &num_sids); - for (entry = ldap_first_entry(conn->ldap_struct, msg); + for (entry = ldap_first_entry(conn->ldap_struct, result); entry != NULL; entry = ldap_next_entry(conn->ldap_struct, entry)) { @@ -2581,15 +2620,12 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, *p_num_groups = num_sids; - result = NT_STATUS_OK; + ret = NT_STATUS_OK; done: SAFE_FREE(escape_name); - if (msg != NULL) - ldap_msgfree(msg); - - return result; + return ret; } /********************************************************************** @@ -2814,9 +2850,10 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods, /* Make 100% sure that sid, gid and type are not changed by looking up * exactly the values we're given in LDAP. */ - filter = talloc_asprintf(mem_ctx, "(&(objectClass=sambaGroupMapping)" + filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)" "(sambaSid=%s)(gidNumber=%u)" "(sambaGroupType=%d))", + LDAP_OBJ_GROUPMAP, sid_string_static(&map->sid), map->gid, map->sid_name_use); if (filter == NULL) { @@ -3613,8 +3650,7 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods, for (i=0; ismbldap_state, filter, NULL, &result); @@ -4625,8 +4665,7 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods, return ret; } - sid_copy(&user_sid, get_global_sam_sid()); - sid_append_rid(&user_sid, *rid); + sid_compose(&user_sid, get_global_sam_sid(), *rid); user = samu_new(tmp_ctx); if (!user) { @@ -4643,9 +4682,16 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods, return NT_STATUS_UNSUCCESSFUL; } if (is_machine) { - if (!pdb_set_acct_ctrl(user, ACB_WSTRUST | ACB_DISABLED, PDB_SET)) { - DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n")); - return NT_STATUS_UNSUCCESSFUL; + if (acb_info & ACB_NORMAL) { + if (!pdb_set_acct_ctrl(user, ACB_WSTRUST, PDB_SET)) { + DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n")); + return NT_STATUS_UNSUCCESSFUL; + } + } else { + if (!pdb_set_acct_ctrl(user, acb_info, PDB_SET)) { + DEBUG(1,("ldapsam_create_user: Unable to fill user structs\n")); + return NT_STATUS_UNSUCCESSFUL; + } } } else { if (!pdb_set_acct_ctrl(user, ACB_NORMAL | ACB_DISABLED, PDB_SET)) { @@ -4664,17 +4710,10 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods, return NT_STATUS_UNSUCCESSFUL; } - switch ( ldap_state->schema_ver ) { - case SCHEMAVER_SAMBAACCOUNT: - smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBAACCOUNT); - break; - case SCHEMAVER_SAMBASAMACCOUNT: - smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT); - break; - default: - DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n")); - break; + if (ldap_state->schema_ver != SCHEMAVER_SAMBASAMACCOUNT) { + DEBUG(1,("ldapsam_create_user: Unsupported schema version\n")); } + smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SAMBASAMACCOUNT); if (add_posix) { DEBUG(3,("ldapsam_create_user: Creating new posix user\n")); @@ -4757,9 +4796,11 @@ static NTSTATUS ldapsam_delete_user(struct pdb_methods *my_methods, TALLOC_CTX * filter = talloc_asprintf(tmp_ctx, "(&(uid=%s)" - "(objectClass=posixAccount)" - "(objectClass=sambaSamAccount))", - pdb_get_username(sam_acct)); + "(objectClass=%s)" + "(objectClass=%s))", + pdb_get_username(sam_acct), + LDAP_OBJ_POSIXACCOUNT, + LDAP_OBJ_SAMBASAMACCOUNT); rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result); if (rc != LDAP_SUCCESS) { @@ -4833,7 +4874,8 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods, int rc; groupname = escape_ldap_string_alloc(name); - filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass=posixGroup))", groupname); + filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass=%s))", + groupname, LDAP_OBJ_POSIXGROUP); SAFE_FREE(groupname); rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result); @@ -4912,8 +4954,7 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods, return ret; } - sid_copy(&group_sid, get_global_sam_sid()); - sid_append_rid(&group_sid, *rid); + sid_compose(&group_sid, get_global_sam_sid(), *rid); groupsidstr = talloc_strdup(tmp_ctx, sid_string_static(&group_sid)); grouptype = talloc_asprintf(tmp_ctx, "%d", SID_NAME_DOM_GRP); @@ -4923,7 +4964,7 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods, return NT_STATUS_NO_MEMORY; } - smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", "sambaGroupMapping"); + smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP); smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaSid", groupsidstr); smbldap_set_mod(&mods, LDAP_MOD_ADD, "sambaGroupType", grouptype); smbldap_set_mod(&mods, LDAP_MOD_ADD, "displayName", name); @@ -4966,14 +5007,15 @@ static NTSTATUS ldapsam_delete_dom_group(struct pdb_methods *my_methods, TALLOC_ int rc; /* get the group sid */ - sid_copy(&group_sid, get_global_sam_sid()); - sid_append_rid(&group_sid, rid); + sid_compose(&group_sid, get_global_sam_sid(), rid); filter = talloc_asprintf(tmp_ctx, "(&(sambaSID=%s)" - "(objectClass=posixGroup)" - "(objectClass=sambaGroupMapping))", - sid_string_static(&group_sid)); + "(objectClass=%s)" + "(objectClass=%s))", + sid_string_static(&group_sid), + LDAP_OBJ_POSIXGROUP, + LDAP_OBJ_GROUPMAP); rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result); if (rc != LDAP_SUCCESS) { @@ -5015,9 +5057,11 @@ static NTSTATUS ldapsam_delete_dom_group(struct pdb_methods *my_methods, TALLOC_ /* check no user have this group marked as primary group */ filter = talloc_asprintf(tmp_ctx, "(&(gidNumber=%s)" - "(objectClass=posixAccount)" - "(objectClass=sambaSamAccount))", - gidstr); + "(objectClass=%s)" + "(objectClass=%s))", + gidstr, + LDAP_OBJ_POSIXACCOUNT, + LDAP_OBJ_SAMBASAMACCOUNT); rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result); if (rc != LDAP_SUCCESS) { @@ -5071,18 +5115,18 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods, } /* get member sid */ - sid_copy(&member_sid, get_global_sam_sid()); - sid_append_rid(&member_sid, member_rid); + sid_compose(&member_sid, get_global_sam_sid(), member_rid); /* get the group sid */ - sid_copy(&group_sid, get_global_sam_sid()); - sid_append_rid(&group_sid, group_rid); + sid_compose(&group_sid, get_global_sam_sid(), group_rid); filter = talloc_asprintf(tmp_ctx, "(&(sambaSID=%s)" - "(objectClass=posixAccount)" - "(objectClass=sambaSamAccount))", - sid_string_static(&member_sid)); + "(objectClass=%s)" + "(objectClass=%s))", + sid_string_static(&member_sid), + LDAP_OBJ_POSIXACCOUNT, + LDAP_OBJ_SAMBASAMACCOUNT); /* get the member uid */ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result); @@ -5142,9 +5186,11 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods, filter = talloc_asprintf(tmp_ctx, "(&(sambaSID=%s)" - "(objectClass=posixGroup)" - "(objectClass=sambaGroupMapping))", - sid_string_static(&group_sid)); + "(objectClass=%s)" + "(objectClass=%s))", + sid_string_static(&group_sid), + LDAP_OBJ_POSIXGROUP, + LDAP_OBJ_GROUPMAP); /* get the group */ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result); @@ -5242,9 +5288,11 @@ static NTSTATUS ldapsam_set_primary_group(struct pdb_methods *my_methods, filter = talloc_asprintf(mem_ctx, "(&(uid=%s)" - "(objectClass=posixAccount)" - "(objectClass=sambaSamAccount))", - pdb_get_username(sampass)); + "(objectClass=%s)" + "(objectClass=%s))", + pdb_get_username(sampass), + LDAP_OBJ_POSIXACCOUNT, + LDAP_OBJ_SAMBASAMACCOUNT); rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, NULL, &result); if (rc != LDAP_SUCCESS) { diff --git a/source/utils/net_sam.c b/source/utils/net_sam.c index ea0544abf3a..9c8d72b42f0 100644 --- a/source/utils/net_sam.c +++ b/source/utils/net_sam.c @@ -747,6 +747,390 @@ static int net_sam_show(int argc, const char **argv) return 0; } +/* + * 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; + } + + ldap_bk = talloc_strdup(tc, lp_passdb_backend()); + 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; + } + pwd = talloc(tc, struct passwd); + 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; +} + /*********************************************************** migrated functionality from smbgroupedit **********************************************************/ @@ -769,6 +1153,8 @@ int net_sam(int argc, const char **argv) "Show details of a SAM entry" }, { "set", net_sam_set, "Set details of a SAM account" }, + { "provision", net_sam_provision, + "Provision a clean User Database" }, { NULL, NULL, NULL } }; -- 2.11.4.GIT