예제 #1
0
파일: lsa_lookup.c 프로젝트: endisd/samba
/*
  lookup a name for 1 SID
*/
static NTSTATUS dcesrv_lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
                                      struct dom_sid *sid, const char *sid_str,
                                      const char **authority_name,
                                      const char **name, enum lsa_SidType *rtype)
{
    NTSTATUS status;
    int ret;
    uint32_t atype;
    struct ldb_message **res;
    struct ldb_dn *domain_dn;
    const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "cn", NULL};

    status = lookup_well_known_sids(mem_ctx, sid_str, authority_name, name, rtype);
    if (NT_STATUS_IS_OK(status)) {
        return status;
    }

    if (dom_sid_in_domain(state->domain_sid, sid)) {
        *authority_name = state->domain_name;
        domain_dn = state->domain_dn;
    } else if (dom_sid_in_domain(state->builtin_sid, sid)) {
        *authority_name = NAME_BUILTIN;
        domain_dn = state->builtin_dn;
    } else {
        /* Not well known, our domain or built in */

        /* In future, we must look at SID histories, and at trusted domains via winbind */

        return NT_STATUS_NOT_FOUND;
    }

    ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs,
                       "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid));
    if (ret == 1) {
        *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
        if (!*name) {
            *name = ldb_msg_find_attr_as_string(res[0], "cn", NULL);
            if (!*name) {
                *name = talloc_strdup(mem_ctx, sid_str);
                NT_STATUS_HAVE_NO_MEMORY(*name);
            }
        }

        atype = samdb_result_uint(res[0], "sAMAccountType", 0);

        *rtype = ds_atype_map(atype);

        return NT_STATUS_OK;
    }

    /* need to re-add a check for an allocated sid */

    return NT_STATUS_NOT_FOUND;
}
예제 #2
0
파일: lsa_lookup.c 프로젝트: endisd/samba
/*
  lookup a SID for 1 name
*/
static NTSTATUS dcesrv_lsa_lookup_name(struct tevent_context *ev_ctx,
                                       struct loadparm_context *lp_ctx,
                                       struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
                                       const char *name, const char **authority_name,
                                       struct dom_sid **sid, enum lsa_SidType *rtype,
                                       uint32_t *rid)
{
    int ret, i;
    uint32_t atype;
    struct ldb_message **res;
    const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
    const char *p;
    const char *domain;
    const char *username;
    struct ldb_dn *domain_dn;
    struct dom_sid *domain_sid;
    NTSTATUS status;

    p = strchr_m(name, '\\');
    if (p != NULL) {
        domain = talloc_strndup(mem_ctx, name, p-name);
        if (!domain) {
            return NT_STATUS_NO_MEMORY;
        }
        username = p + 1;
    } else if (strchr_m(name, '@')) {
        status = crack_name_to_nt4_name(mem_ctx, ev_ctx, lp_ctx, DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL, name, &domain, &username);
        if (!NT_STATUS_IS_OK(status)) {
            DEBUG(3, ("Failed to crack name %s into an NT4 name: %s\n", name, nt_errstr(status)));
            return status;
        }
    } else {
        domain = NULL;
        username = name;
    }

    if (!domain) {
        /* Look up table of well known names */
        status = lookup_well_known_names(mem_ctx, NULL, username, authority_name, sid, rtype);
        if (NT_STATUS_IS_OK(status)) {
            dom_sid_split_rid(NULL, *sid, NULL, rid);
            return NT_STATUS_OK;
        }

        if (username == NULL) {
            *authority_name = NAME_BUILTIN;
            *sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN);
            *rtype = SID_NAME_DOMAIN;
            *rid = 0xFFFFFFFF;
            return NT_STATUS_OK;
        }

        if (strcasecmp_m(username, NAME_NT_AUTHORITY) == 0) {
            *authority_name = NAME_NT_AUTHORITY;
            *sid =  dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY);
            *rtype = SID_NAME_DOMAIN;
            dom_sid_split_rid(NULL, *sid, NULL, rid);
            return NT_STATUS_OK;
        }
        if (strcasecmp_m(username, NAME_BUILTIN) == 0) {
            *authority_name = NAME_BUILTIN;
            *sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN);
            *rtype = SID_NAME_DOMAIN;
            *rid = 0xFFFFFFFF;
            return NT_STATUS_OK;
        }
        if (strcasecmp_m(username, state->domain_dns) == 0) {
            *authority_name = state->domain_name;
            *sid =  state->domain_sid;
            *rtype = SID_NAME_DOMAIN;
            *rid = 0xFFFFFFFF;
            return NT_STATUS_OK;
        }
        if (strcasecmp_m(username, state->domain_name) == 0) {
            *authority_name = state->domain_name;
            *sid =  state->domain_sid;
            *rtype = SID_NAME_DOMAIN;
            *rid = 0xFFFFFFFF;
            return NT_STATUS_OK;
        }

        /* Perhaps this is a well known user? */
        name = talloc_asprintf(mem_ctx, "%s\\%s", NAME_NT_AUTHORITY, username);
        if (!name) {
            return NT_STATUS_NO_MEMORY;
        }
        status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype, rid);
        if (NT_STATUS_IS_OK(status)) {
            return status;
        }

        /* Perhaps this is a BUILTIN user? */
        name = talloc_asprintf(mem_ctx, "%s\\%s", NAME_BUILTIN, username);
        if (!name) {
            return NT_STATUS_NO_MEMORY;
        }
        status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype, rid);
        if (NT_STATUS_IS_OK(status)) {
            return status;
        }

        /* OK, I give up - perhaps we need to assume the user is in our domain? */
        name = talloc_asprintf(mem_ctx, "%s\\%s", state->domain_name, username);
        if (!name) {
            return NT_STATUS_NO_MEMORY;
        }
        status = dcesrv_lsa_lookup_name(ev_ctx, lp_ctx, state, mem_ctx, name, authority_name, sid, rtype, rid);
        if (NT_STATUS_IS_OK(status)) {
            return status;
        }

        return STATUS_SOME_UNMAPPED;
    } else if (strcasecmp_m(domain, NAME_NT_AUTHORITY) == 0) {
        if (!*username) {
            *authority_name = NAME_NT_AUTHORITY;
            *sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY);
            *rtype = SID_NAME_DOMAIN;
            dom_sid_split_rid(NULL, *sid, NULL, rid);
            return NT_STATUS_OK;
        }

        /* Look up table of well known names */
        status = lookup_well_known_names(mem_ctx, domain, username, authority_name,
                                         sid, rtype);
        if (NT_STATUS_IS_OK(status)) {
            dom_sid_split_rid(NULL, *sid, NULL, rid);
        }
        return status;
    } else if (strcasecmp_m(domain, NAME_BUILTIN) == 0) {
        *authority_name = NAME_BUILTIN;
        domain_dn = state->builtin_dn;
    } else if (strcasecmp_m(domain, state->domain_dns) == 0) {
        *authority_name = state->domain_name;
        domain_dn = state->domain_dn;
    } else if (strcasecmp_m(domain, state->domain_name) == 0) {
        *authority_name = state->domain_name;
        domain_dn = state->domain_dn;
    } else {
        /* Not local, need to ask winbind in future */
        return STATUS_SOME_UNMAPPED;
    }

    ret = gendb_search_dn(state->sam_ldb, mem_ctx, domain_dn, &res, attrs);
    if (ret == 1) {
        domain_sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
        if (domain_sid == NULL) {
            return NT_STATUS_INVALID_SID;
        }
    } else {
        return NT_STATUS_INVALID_SID;
    }

    if (!*username) {
        *sid = domain_sid;
        *rtype = SID_NAME_DOMAIN;
        *rid = 0xFFFFFFFF;
        return NT_STATUS_OK;
    }

    ret = gendb_search(state->sam_ldb, mem_ctx, domain_dn, &res, attrs,
                       "(&(sAMAccountName=%s)(objectSid=*))",
                       ldb_binary_encode_string(mem_ctx, username));
    if (ret == -1) {
        return NT_STATUS_INVALID_SID;
    }

    for (i=0; i < ret; i++) {
        *sid = samdb_result_dom_sid(mem_ctx, res[i], "objectSid");
        if (*sid == NULL) {
            return NT_STATUS_INVALID_SID;
        }

        /* Check that this is in the domain */
        if (!dom_sid_in_domain(domain_sid, *sid)) {
            continue;
        }

        atype = samdb_result_uint(res[i], "sAMAccountType", 0);

        *rtype = ds_atype_map(atype);
        if (*rtype == SID_NAME_UNKNOWN) {
            return STATUS_SOME_UNMAPPED;
        }

        dom_sid_split_rid(NULL, *sid, NULL, rid);
        return NT_STATUS_OK;
    }

    /* need to check for an allocated sid */

    return NT_STATUS_INVALID_SID;
}
예제 #3
0
/* 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 *num_entries, 
			       struct wbint_userinfo **pinfo)
{
	ADS_STRUCT *ads = NULL;
	const char *attrs[] = { "*", NULL };
	int i, count;
	ADS_STATUS rc;
	LDAPMessage *res = NULL;
	LDAPMessage *msg = NULL;
	NTSTATUS status = NT_STATUS_UNSUCCESSFUL;

	*num_entries = 0;

	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) || !res) {
		DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc)));
		goto done;
	}

	count = ads_count_replies(ads, res);
	if (count == 0) {
		DEBUG(1,("query_user_list: No users found\n"));
		goto done;
	}

	(*pinfo) = talloc_zero_array(mem_ctx, struct wbint_userinfo, count);
	if (!*pinfo) {
		status = NT_STATUS_NO_MEMORY;
		goto done;
	}

	count = 0;

	for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
		struct wbint_userinfo *info = &((*pinfo)[count]);
		uint32 group;
		uint32 atype;

		if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype) ||
		    ds_atype_map(atype) != SID_NAME_USER) {
			DEBUG(1,("Not a user account? atype=0x%x\n", atype));
			continue;
		}

		info->acct_name = ads_pull_username(ads, mem_ctx, msg);
		info->full_name = ads_pull_string(ads, mem_ctx, msg, "name");
		info->homedir = NULL;
		info->shell = NULL;
		info->primary_gid = (gid_t)-1;

		if (!ads_pull_sid(ads, msg, "objectSid",
				  &info->user_sid)) {
			DEBUG(1, ("No sid for %s !?\n", info->acct_name));
			continue;
		}

		if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group)) {
			DEBUG(1, ("No primary group for %s !?\n",
				  info->acct_name));
			continue;
		}
		sid_compose(&info->group_sid, &domain->sid, group);

		count += 1;
	}

	(*num_entries) = count;
	ads_msgfree(ads, res);

	for (i=0; i<count; i++) {
		struct wbint_userinfo *info = &((*pinfo)[i]);
		const char *gecos = NULL;
		gid_t primary_gid = (gid_t)-1;

		status = nss_get_info_cached(domain, &info->user_sid, mem_ctx,
					     &info->homedir, &info->shell,
					     &gecos, &primary_gid);
		if (!NT_STATUS_IS_OK(status)) {
			/*
			 * Deliberately ignore this error, there might be more
			 * users to fill
			 */
			continue;
		}

		if (gecos != NULL) {
			info->full_name = gecos;
		}
		info->primary_gid = primary_gid;
	}

	status = NT_STATUS_OK;

	DEBUG(3,("ads query_user_list gave %d entries\n", (*num_entries)));

done:
	return status;
}
예제 #4
0
/* 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;
}
예제 #5
0
/* 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 *num_entries, 
			       struct wbint_userinfo **info)
{
	ADS_STRUCT *ads = NULL;
	const char *attrs[] = { "*", NULL };
	int i, count;
	ADS_STATUS rc;
	LDAPMessage *res = NULL;
	LDAPMessage *msg = NULL;
	NTSTATUS status = NT_STATUS_UNSUCCESSFUL;

	*num_entries = 0;

	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) || !res) {
		DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc)));
		goto done;
	}

	count = ads_count_replies(ads, res);
	if (count == 0) {
		DEBUG(1,("query_user_list: No users found\n"));
		goto done;
	}

	(*info) = TALLOC_ZERO_ARRAY(mem_ctx, struct wbint_userinfo, count);
	if (!*info) {
		status = NT_STATUS_NO_MEMORY;
		goto done;
	}

	i = 0;

	for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
		const char *name;
		const char *gecos = NULL;
		const char *homedir = NULL;
		const char *shell = NULL;
		uint32 group;
		uint32 atype;
		DOM_SID user_sid;
		gid_t primary_gid = (gid_t)-1;

		if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype) ||
		    ds_atype_map(atype) != SID_NAME_USER) {
			DEBUG(1,("Not a user account? atype=0x%x\n", atype));
			continue;
		}

		name = ads_pull_username(ads, mem_ctx, msg);

		if ( ads_pull_sid( ads, msg, "objectSid", &user_sid ) ) {
			status = nss_get_info_cached( domain, &user_sid, mem_ctx, 
					       ads, msg, &homedir, &shell, &gecos,
					       &primary_gid );
		}

		if (gecos == NULL) {
			gecos = ads_pull_string(ads, mem_ctx, msg, "name");
		}

		if (!ads_pull_sid(ads, msg, "objectSid",
				  &(*info)[i].user_sid)) {
			DEBUG(1,("No sid for %s !?\n", name));
			continue;
		}
		if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group)) {
			DEBUG(1,("No primary group for %s !?\n", name));
			continue;
		}

		(*info)[i].acct_name = name;
		(*info)[i].full_name = gecos;
		(*info)[i].homedir = homedir;
		(*info)[i].shell = shell;
		(*info)[i].primary_gid = primary_gid;
		sid_compose(&(*info)[i].group_sid, &domain->sid, group);
		i++;
	}

	(*num_entries) = i;
	status = NT_STATUS_OK;

	DEBUG(3,("ads query_user_list gave %d entries\n", (*num_entries)));

done:
	if (res) 
		ads_msgfree(ads, res);

	return status;
}
예제 #6
0
파일: util_samr.c 프로젝트: Arkhont/samba
NTSTATUS dsdb_lookup_rids(struct ldb_context *ldb,
			  TALLOC_CTX *mem_ctx,
			  const struct dom_sid *domain_sid,
			  unsigned int num_rids,
			  uint32_t *rids,
			  const char **names,
			  enum lsa_SidType *lsa_attrs)
{
	const char *attrs[] = { "sAMAccountType", "sAMAccountName", NULL };
	unsigned int i, num_mapped;

	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);

	num_mapped = 0;

	for (i=0; i<num_rids; i++) {
		struct ldb_message *msg;
		struct ldb_dn *dn;
		uint32_t attr;
		int rc;

		lsa_attrs[i] = SID_NAME_UNKNOWN;

		dn = ldb_dn_new_fmt(tmp_ctx, ldb, "<SID=%s>",
				    dom_sid_string(tmp_ctx,
						   dom_sid_add_rid(tmp_ctx, domain_sid,
								   rids[i])));
		if (dn == NULL) {
			talloc_free(tmp_ctx);
			return NT_STATUS_NO_MEMORY;
		}
		rc = dsdb_search_one(ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "samAccountName=*");
		if (rc == LDB_ERR_NO_SUCH_OBJECT) {
			continue;
		} else if (rc != LDB_SUCCESS) {
			talloc_free(tmp_ctx);
			return NT_STATUS_INTERNAL_DB_CORRUPTION;
		}

		names[i] = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
		if (names[i] == NULL) {
			DEBUG(10, ("no samAccountName\n"));
			continue;
		}
		talloc_steal(names, names[i]);
		attr = ldb_msg_find_attr_as_uint(msg, "samAccountType", 0);
		lsa_attrs[i] = ds_atype_map(attr);
		if (lsa_attrs[i] == SID_NAME_UNKNOWN) {
			continue;
		}
		num_mapped += 1;
	}
	talloc_free(tmp_ctx);

	if (num_mapped == 0) {
		return NT_STATUS_NONE_MAPPED;
	}
	if (num_mapped < num_rids) {
		return STATUS_SOME_UNMAPPED;
	}
	return NT_STATUS_OK;
}