static int ads_group_delete(int argc, const char **argv) { ADS_STRUCT *ads; ADS_STATUS rc; void *res; char *groupdn; if (argc < 1) { return net_ads_group_usage(argc, argv); } if (!(ads = ads_startup())) { return -1; } rc = ads_find_user_acct(ads, &res, argv[0]); if (!ADS_ERR_OK(rc)) { DEBUG(0, ("Group %s does not exist\n", argv[0])); ads_destroy(&ads); return -1; } groupdn = ads_get_dn(ads, res); ads_msgfree(ads, res); rc = ads_del_dn(ads, groupdn); ads_memfree(ads, groupdn); if (!ADS_ERR_OK(rc)) { d_printf("Group %s deleted\n", argv[0]); ads_destroy(&ads); return 0; } d_printf("Error deleting group %s: %s\n", argv[0], ads_errstr(rc)); ads_destroy(&ads); return -1; }
static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads, const char *printer) { ADS_STATUS ads_rc; LDAPMessage *res = NULL; char *prt_dn = NULL; DEBUG(5, ("unpublishing printer %s\n", printer)); /* remove the printer from the directory */ ads_rc = ads_find_printer_on_server(ads, &res, printer, lp_netbios_name()); if (ADS_ERR_OK(ads_rc) && res && ads_count_replies(ads, res)) { prt_dn = ads_get_dn(ads, talloc_tos(), res); if (!prt_dn) { ads_msgfree(ads, res); return WERR_NOMEM; } ads_rc = ads_del_dn(ads, prt_dn); TALLOC_FREE(prt_dn); } if (res) { ads_msgfree(ads, res); } return WERR_OK; }
static int net_ads_printer_remove(int argc, const char **argv) { ADS_STRUCT *ads; ADS_STATUS rc; const char *servername; char *prt_dn; void *res = NULL; if (!(ads = ads_startup())) { return -1; } if (argc < 1) { return net_ads_printer_usage(argc, argv); } if (argc > 1) { servername = argv[1]; } else { servername = global_myname(); } rc = ads_find_printer_on_server(ads, &res, argv[0], servername); if (!ADS_ERR_OK(rc)) { d_printf("ads_find_printer_on_server: %s\n", ads_errstr(rc)); ads_msgfree(ads, res); ads_destroy(&ads); return -1; } if (ads_count_replies(ads, res) == 0) { d_printf("Printer '%s' not found\n", argv[1]); ads_msgfree(ads, res); ads_destroy(&ads); return -1; } prt_dn = ads_get_dn(ads, res); ads_msgfree(ads, res); rc = ads_del_dn(ads, prt_dn); ads_memfree(ads, prt_dn); if (!ADS_ERR_OK(rc)) { d_printf("ads_del_dn: %s\n", ads_errstr(rc)); ads_destroy(&ads); return -1; } ads_destroy(&ads); return 0; }
static int ads_user_add(int argc, const char **argv) { ADS_STRUCT *ads; ADS_STATUS status; char *upn, *userdn; void *res=NULL; int rc = -1; if (argc < 1) return net_ads_user_usage(argc, argv); if (!(ads = ads_startup())) { return -1; } status = ads_find_user_acct(ads, &res, argv[0]); if (!ADS_ERR_OK(status)) { d_printf("ads_user_add: %s\n", ads_errstr(status)); goto done; } if (ads_count_replies(ads, res)) { d_printf("ads_user_add: User %s already exists\n", argv[0]); goto done; } status = ads_add_user_acct(ads, argv[0], opt_container, opt_comment); if (!ADS_ERR_OK(status)) { d_printf("Could not add user %s: %s\n", argv[0], ads_errstr(status)); goto done; } /* if no password is to be set, we're done */ if (argc == 1) { d_printf("User %s added\n", argv[0]); rc = 0; goto done; } /* try setting the password */ asprintf(&upn, "%s@%s", argv[0], ads->config.realm); status = ads_krb5_set_password(ads->auth.kdc_server, upn, argv[1], ads->auth.time_offset); safe_free(upn); if (ADS_ERR_OK(status)) { d_printf("User %s added\n", argv[0]); rc = 0; goto done; } /* password didn't set, delete account */ d_printf("Could not add user %s. Error setting password %s\n", argv[0], ads_errstr(status)); ads_msgfree(ads, res); status=ads_find_user_acct(ads, &res, argv[0]); if (ADS_ERR_OK(status)) { userdn = ads_get_dn(ads, res); ads_del_dn(ads, userdn); ads_memfree(ads, userdn); } done: if (res) ads_msgfree(ads, res); ads_destroy(&ads); return rc; }
/* Lookup groups a user is a member of. */ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, const struct dom_sid *sid, uint32 *p_num_groups, struct dom_sid **user_sids) { ADS_STRUCT *ads = NULL; const char *attrs[] = {"tokenGroups", "primaryGroupID", NULL}; ADS_STATUS rc; int count; LDAPMessage *msg = NULL; char *user_dn = NULL; struct dom_sid *sids; int i; struct dom_sid primary_group; uint32 primary_group_rid; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; uint32_t num_groups = 0; DEBUG(3,("ads: lookup_usergroups\n")); *p_num_groups = 0; status = lookup_usergroups_cached(domain, mem_ctx, sid, p_num_groups, user_sids); if (NT_STATUS_IS_OK(status)) { return NT_STATUS_OK; } if ( !winbindd_can_contact_domain( domain ) ) { DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n", domain->name)); /* Tell the cache manager not to remember this one */ return NT_STATUS_SYNCHRONIZATION_REQUIRED; } ads = ads_cached_connection(domain); if (!ads) { domain->last_status = NT_STATUS_SERVER_DISABLED; status = NT_STATUS_SERVER_DISABLED; goto done; } rc = ads_search_retry_sid(ads, &msg, sid, attrs); if (!ADS_ERR_OK(rc)) { status = ads_ntstatus(rc); DEBUG(1, ("lookup_usergroups(sid=%s) ads_search tokenGroups: " "%s\n", sid_string_dbg(sid), ads_errstr(rc))); goto done; } count = ads_count_replies(ads, msg); if (count != 1) { status = NT_STATUS_UNSUCCESSFUL; DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: " "invalid number of results (count=%d)\n", sid_string_dbg(sid), count)); goto done; } if (!msg) { DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: NULL msg\n", sid_string_dbg(sid))); status = NT_STATUS_UNSUCCESSFUL; goto done; } user_dn = ads_get_dn(ads, mem_ctx, msg); if (user_dn == NULL) { status = NT_STATUS_NO_MEMORY; goto done; } if (!ads_pull_uint32(ads, msg, "primaryGroupID", &primary_group_rid)) { DEBUG(1,("%s: No primary group for sid=%s !?\n", domain->name, sid_string_dbg(sid))); goto done; } sid_compose(&primary_group, &domain->sid, primary_group_rid); count = ads_pull_sids(ads, mem_ctx, msg, "tokenGroups", &sids); /* there must always be at least one group in the token, unless we are talking to a buggy Win2k server */ /* actually this only happens when the machine account has no read * permissions on the tokenGroup attribute - gd */ if (count == 0) { /* no tokenGroups */ /* lookup what groups this user is a member of by DN search on * "memberOf" */ status = lookup_usergroups_memberof(domain, mem_ctx, user_dn, &primary_group, &num_groups, user_sids); *p_num_groups = num_groups; if (NT_STATUS_IS_OK(status)) { goto done; } /* lookup what groups this user is a member of by DN search on * "member" */ status = lookup_usergroups_member(domain, mem_ctx, user_dn, &primary_group, &num_groups, user_sids); *p_num_groups = num_groups; goto done; } *user_sids = NULL; num_groups = 0; status = add_sid_to_array(mem_ctx, &primary_group, user_sids, &num_groups); if (!NT_STATUS_IS_OK(status)) { goto done; } for (i=0;i<count;i++) { /* ignore Builtin groups from ADS - Guenther */ if (sid_check_is_in_builtin(&sids[i])) { continue; } status = add_sid_to_array_unique(mem_ctx, &sids[i], user_sids, &num_groups); if (!NT_STATUS_IS_OK(status)) { goto done; } } *p_num_groups = (uint32)num_groups; status = (*user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY; DEBUG(3,("ads lookup_usergroups (tokenGroups) succeeded for sid=%s\n", sid_string_dbg(sid))); done: TALLOC_FREE(user_dn); ads_msgfree(ads, msg); return status; }
ADS_STATUS cell_do_search(struct likewise_cell *c, const char *search_base, int scope, const char *expr, const char **attrs, LDAPMessage ** msg) { int search_count = 0; ADS_STATUS status; NTSTATUS nt_status; /* check for a NULL connection */ if (!c->conn) { nt_status = cell_connect(c); if (!NT_STATUS_IS_OK(nt_status)) { status = ADS_ERROR_NT(nt_status); return status; } } DEBUG(10, ("cell_do_search: Base = %s, Filter = %s, Scope = %d, GC = %s\n", search_base, expr, scope, c->conn->server.gc ? "yes" : "no")); /* we try multiple times in case the ADS_STRUCT is bad and we need to reconnect */ while (search_count < MAX_SEARCH_COUNT) { *msg = NULL; status = ads_do_search(c->conn, search_base, scope, expr, attrs, msg); if (ADS_ERR_OK(status)) { if (DEBUGLEVEL >= 10) { LDAPMessage *e = NULL; int n = ads_count_replies(c->conn, *msg); DEBUG(10,("cell_do_search: Located %d entries\n", n)); for (e=ads_first_entry(c->conn, *msg); e!=NULL; e = ads_next_entry(c->conn, e)) { char *dn = ads_get_dn(c->conn, talloc_tos(), e); DEBUGADD(10,(" dn: %s\n", dn ? dn : "<NULL>")); TALLOC_FREE(dn); } } return status; } DEBUG(5, ("cell_do_search: search[%d] failed (%s)\n", search_count, ads_errstr(status))); search_count++; /* Houston, we have a problem */ if (status.error_type == ENUM_ADS_ERROR_LDAP) { switch (status.err.rc) { case LDAP_TIMELIMIT_EXCEEDED: case LDAP_TIMEOUT: case -1: /* we get this error if we cannot contact the LDAP server */ nt_status = cell_connect(c); if (!NT_STATUS_IS_OK(nt_status)) { status = ADS_ERROR_NT(nt_status); return status; } break; default: /* we're all done here */ return status; } } } DEBUG(5, ("cell_do_search: exceeded maximum search count!\n")); return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); }
ADS_STATUS ads_sid_to_dn(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const DOM_SID *sid, char **dn) { ADS_STATUS rc; LDAPMessage *msg = NULL; LDAPMessage *entry = NULL; char *ldap_exp; char *sidstr = NULL; int count; char *dn2 = NULL; const char *attr[] = { "dn", NULL }; if (!(sidstr = sid_binstring(sid))) { DEBUG(1,("ads_sid_to_dn: sid_binstring failed!\n")); rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); goto done; } if(!(ldap_exp = talloc_asprintf(mem_ctx, "(objectSid=%s)", sidstr))) { DEBUG(1,("ads_sid_to_dn: talloc_asprintf failed!\n")); rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); goto done; } rc = ads_search_retry(ads, (void **)&msg, ldap_exp, attr); if (!ADS_ERR_OK(rc)) { DEBUG(1,("ads_sid_to_dn ads_search: %s\n", ads_errstr(rc))); goto done; } if ((count = ads_count_replies(ads, msg)) != 1) { fstring sid_string; DEBUG(1,("ads_sid_to_dn (sid=%s): Not found (count=%d)\n", sid_to_string(sid_string, sid), count)); rc = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); goto done; } entry = ads_first_entry(ads, msg); dn2 = ads_get_dn(ads, entry); if (!dn2) { rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); goto done; } *dn = talloc_strdup(mem_ctx, dn2); if (!*dn) { ads_memfree(ads, dn2); rc = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); goto done; } rc = ADS_ERROR_NT(NT_STATUS_OK); DEBUG(3,("ads sid_to_dn mapped %s\n", dn2)); SAFE_FREE(dn2); done: if (msg) ads_msgfree(ads, msg); if (dn2) ads_memfree(ads, dn2); SAFE_FREE(sidstr); return rc; }
static NTSTATUS add_primary_group_members( ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, uint32_t rid, char ***all_members, size_t *num_all_members) { char *filter; NTSTATUS status = NT_STATUS_NO_MEMORY; ADS_STATUS rc; const char *attrs[] = { "dn", NULL }; LDAPMessage *res = NULL; LDAPMessage *msg; char **members; size_t num_members; ads_control args; filter = talloc_asprintf( mem_ctx, "(&(objectCategory=user)(primaryGroupID=%u))", (unsigned)rid); if (filter == NULL) { goto done; } args.control = ADS_EXTENDED_DN_OID; args.val = ADS_EXTENDED_DN_HEX_STRING; args.critical = True; rc = ads_do_search_all_args(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, filter, attrs, &args, &res); if (!ADS_ERR_OK(rc)) { status = ads_ntstatus(rc); DEBUG(1,("%s: ads_search: %s\n", __func__, ads_errstr(rc))); goto done; } if (res == NULL) { DEBUG(1,("%s: ads_search returned NULL res\n", __func__)); goto done; } num_members = ads_count_replies(ads, res); DEBUG(10, ("%s: Got %ju primary group members\n", __func__, (uintmax_t)num_members)); if (num_members == 0) { status = NT_STATUS_OK; goto done; } members = talloc_realloc(mem_ctx, *all_members, char *, *num_all_members + num_members); if (members == NULL) { DEBUG(1, ("%s: talloc_realloc failed\n", __func__)); goto done; } *all_members = members; for (msg = ads_first_entry(ads, res); msg != NULL; msg = ads_next_entry(ads, msg)) { char *dn; dn = ads_get_dn(ads, members, msg); if (dn == NULL) { DEBUG(1, ("%s: ads_get_dn failed\n", __func__)); continue; } members[*num_all_members] = dn; *num_all_members += 1; } status = NT_STATUS_OK; done: if (res != NULL) { ads_msgfree(ads, res); } TALLOC_FREE(filter); return status; }
/* Query display info for a realm. This is the basic user list fn */ static NTSTATUS query_user_list(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, uint32_t **prids) { ADS_STRUCT *ads = NULL; const char *attrs[] = { "sAMAccountType", "objectSid", NULL }; int count; uint32_t *rids = NULL; ADS_STATUS rc; LDAPMessage *res = NULL; LDAPMessage *msg = NULL; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; DEBUG(3,("ads: query_user_list\n")); if ( !winbindd_can_contact_domain( domain ) ) { DEBUG(10,("query_user_list: No incoming trust for domain %s\n", domain->name)); return NT_STATUS_OK; } ads = ads_cached_connection(domain); if (!ads) { domain->last_status = NT_STATUS_SERVER_DISABLED; goto done; } rc = ads_search_retry(ads, &res, "(objectCategory=user)", attrs); if (!ADS_ERR_OK(rc)) { DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc))); status = ads_ntstatus(rc); goto done; } else if (!res) { DEBUG(1,("query_user_list ads_search returned NULL res\n")); goto done; } count = ads_count_replies(ads, res); if (count == 0) { DEBUG(1,("query_user_list: No users found\n")); goto done; } rids = talloc_zero_array(mem_ctx, uint32_t, count); if (rids == NULL) { status = NT_STATUS_NO_MEMORY; goto done; } count = 0; for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { struct dom_sid user_sid; uint32_t atype; bool ok; ok = ads_pull_uint32(ads, msg, "sAMAccountType", &atype); if (!ok) { DBG_INFO("Object lacks sAMAccountType attribute\n"); continue; } if (ds_atype_map(atype) != SID_NAME_USER) { DBG_INFO("Not a user account? atype=0x%x\n", atype); continue; } if (!ads_pull_sid(ads, msg, "objectSid", &user_sid)) { char *dn = ads_get_dn(ads, talloc_tos(), msg); DBG_INFO("No sid for %s !?\n", dn); TALLOC_FREE(dn); continue; } if (!dom_sid_in_domain(&domain->sid, &user_sid)) { fstring sidstr, domstr; DBG_WARNING("Got sid %s in domain %s\n", sid_to_fstring(sidstr, &user_sid), sid_to_fstring(domstr, &domain->sid)); continue; } sid_split_rid(&user_sid, &rids[count]); count += 1; } rids = talloc_realloc(mem_ctx, rids, uint32_t, count); if (prids != NULL) { *prids = rids; } status = NT_STATUS_OK; DBG_NOTICE("ads query_user_list gave %d entries\n", count); done: return status; }
static int net_ads_gpo_list_all(struct net_context *c, int argc, const char **argv) { ADS_STRUCT *ads; ADS_STATUS status; LDAPMessage *res = NULL; int num_reply = 0; LDAPMessage *msg = NULL; struct GROUP_POLICY_OBJECT gpo; TALLOC_CTX *mem_ctx; char *dn; const char *attrs[] = { "versionNumber", "flags", "gPCFileSysPath", "displayName", "name", "gPCMachineExtensionNames", "gPCUserExtensionNames", "ntSecurityDescriptor", NULL }; if (c->display_usage) { d_printf("Usage:\n" "net ads gpo listall\n" " List all GPOs on the DC\n"); return 0; } mem_ctx = talloc_init("net_ads_gpo_list_all"); if (mem_ctx == NULL) { return -1; } status = ads_startup(c, false, &ads); if (!ADS_ERR_OK(status)) { goto out; } status = ads_do_search_all_sd_flags(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, "(objectclass=groupPolicyContainer)", attrs, DACL_SECURITY_INFORMATION, &res); if (!ADS_ERR_OK(status)) { d_printf("search failed: %s\n", ads_errstr(status)); goto out; } num_reply = ads_count_replies(ads, res); d_printf("Got %d replies\n\n", num_reply); /* dump the results */ for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { if ((dn = ads_get_dn(ads, mem_ctx, msg)) == NULL) { goto out; } status = ads_parse_gpo(ads, mem_ctx, msg, dn, &gpo); if (!ADS_ERR_OK(status)) { d_printf("ads_parse_gpo failed: %s\n", ads_errstr(status)); goto out; } dump_gpo(ads, mem_ctx, &gpo, 0); } out: ads_msgfree(ads, res); TALLOC_FREE(mem_ctx); ads_destroy(&ads); return 0; }