Beispiel #1
0
static NTSTATUS idmap_ldap_unixids_to_sids(struct idmap_domain *dom,
					   struct id_map **ids)
{
	NTSTATUS ret;
	TALLOC_CTX *memctx;
	struct idmap_ldap_context *ctx;
	LDAPMessage *result = NULL;
	LDAPMessage *entry = NULL;
	const char *uidNumber;
	const char *gidNumber;
	const char **attr_list;
	char *filter = NULL;
	bool multi = False;
	int idx = 0;
	int bidx = 0;
	int count;
	int rc;
	int i;

	/* Only do query if we are online */
	if (idmap_is_offline())	{
		return NT_STATUS_FILE_IS_OFFLINE;
	}

	/* Initilization my have been deferred because we were offline */
	if ( ! dom->initialized) {
		ret = idmap_ldap_db_init(dom);
		if ( ! NT_STATUS_IS_OK(ret)) {
			return ret;
		}
	}

	ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);

	memctx = talloc_new(ctx);
	if ( ! memctx) {
		DEBUG(0, ("Out of memory!\n"));
		return NT_STATUS_NO_MEMORY;
	}

	uidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_UIDNUMBER);
	gidNumber = get_attr_key2string(idpool_attr_list, LDAP_ATTR_GIDNUMBER);

	attr_list = get_attr_list(memctx, sidmap_attr_list);

	if ( ! ids[1]) {
		/* if we are requested just one mapping use the simple filter */

		filter = talloc_asprintf(memctx, "(&(objectClass=%s)(%s=%lu))",
				LDAP_OBJ_IDMAP_ENTRY,
				(ids[0]->xid.type==ID_TYPE_UID)?uidNumber:gidNumber,
				(unsigned long)ids[0]->xid.id);
		CHECK_ALLOC_DONE(filter);
		DEBUG(10, ("Filter: [%s]\n", filter));
	} else {
		/* multiple mappings */
		multi = True;
	}

	for (i = 0; ids[i]; i++) {
		ids[i]->status = ID_UNKNOWN;
	}

again:
	if (multi) {

		talloc_free(filter);
		filter = talloc_asprintf(memctx,
					 "(&(objectClass=%s)(|",
					 LDAP_OBJ_IDMAP_ENTRY);
		CHECK_ALLOC_DONE(filter);

		bidx = idx;
		for (i = 0; (i < IDMAP_LDAP_MAX_IDS) && ids[idx]; i++, idx++) {
			filter = talloc_asprintf_append_buffer(filter, "(%s=%lu)",
					(ids[idx]->xid.type==ID_TYPE_UID)?uidNumber:gidNumber,
					(unsigned long)ids[idx]->xid.id);
			CHECK_ALLOC_DONE(filter);
		}
		filter = talloc_asprintf_append_buffer(filter, "))");
		CHECK_ALLOC_DONE(filter);
		DEBUG(10, ("Filter: [%s]\n", filter));
	} else {
		bidx = 0;
		idx = 1;
	}

	rc = smbldap_search(ctx->smbldap_state, ctx->suffix, LDAP_SCOPE_SUBTREE,
		filter, attr_list, 0, &result);

	if (rc != LDAP_SUCCESS) {
		DEBUG(3,("Failure looking up ids (%s)\n", ldap_err2string(rc)));
		ret = NT_STATUS_UNSUCCESSFUL;
		goto done;
	}

	count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result);

	if (count == 0) {
		DEBUG(10, ("NO SIDs found\n"));
	}

	for (i = 0; i < count; i++) {
		char *sidstr = NULL;
	       	char *tmp = NULL;
		enum id_type type;
		struct id_map *map;
		uint32_t id;

		if (i == 0) { /* first entry */
			entry = ldap_first_entry(ctx->smbldap_state->ldap_struct,
						 result);
		} else { /* following ones */
			entry = ldap_next_entry(ctx->smbldap_state->ldap_struct,
						entry);
		}
		if ( ! entry) {
			DEBUG(2, ("ERROR: Unable to fetch ldap entries "
				  "from results\n"));
			break;
		}

		/* first check if the SID is present */
		sidstr = smbldap_talloc_single_attribute(
				ctx->smbldap_state->ldap_struct,
				entry, LDAP_ATTRIBUTE_SID, memctx);
		if ( ! sidstr) { /* no sid, skip entry */
			DEBUG(2, ("WARNING SID not found on entry\n"));
			continue;
		}

		/* now try to see if it is a uid, if not try with a gid
		 * (gid is more common, but in case both uidNumber and
		 * gidNumber are returned the SID is mapped to the uid
		 *not the gid) */
		type = ID_TYPE_UID;
		tmp = smbldap_talloc_single_attribute(
				ctx->smbldap_state->ldap_struct,
				entry, uidNumber, memctx);
		if ( ! tmp) {
			type = ID_TYPE_GID;
			tmp = smbldap_talloc_single_attribute(
					ctx->smbldap_state->ldap_struct,
					entry, gidNumber, memctx);
		}
		if ( ! tmp) { /* wow very strange entry, how did it match ? */
			DEBUG(5, ("Unprobable match on (%s), no uidNumber, "
				  "nor gidNumber returned\n", sidstr));
			TALLOC_FREE(sidstr);
			continue;
		}

		id = strtoul(tmp, NULL, 10);
		if ((id == 0) ||
		    (ctx->filter_low_id && (id < ctx->filter_low_id)) ||
		    (ctx->filter_high_id && (id > ctx->filter_high_id))) {
			DEBUG(5, ("Requested id (%u) out of range (%u - %u). "
				  "Filtered!\n", id,
				  ctx->filter_low_id, ctx->filter_high_id));
			TALLOC_FREE(sidstr);
			TALLOC_FREE(tmp);
			continue;
		}
		TALLOC_FREE(tmp);

		map = find_map_by_id(&ids[bidx], type, id);
		if (!map) {
			DEBUG(2, ("WARNING: couldn't match sid (%s) "
				  "with requested ids\n", sidstr));
			TALLOC_FREE(sidstr);
			continue;
		}

		if ( ! string_to_sid(map->sid, sidstr)) {
			DEBUG(2, ("ERROR: Invalid SID on entry\n"));
			TALLOC_FREE(sidstr);
			continue;
		}
		TALLOC_FREE(sidstr);

		/* mapped */
		map->status = ID_MAPPED;

		DEBUG(10, ("Mapped %s -> %lu (%d)\n", sid_string_dbg(map->sid),
			   (unsigned long)map->xid.id, map->xid.type));
	}

	/* free the ldap results */
	if (result) {
		ldap_msgfree(result);
		result = NULL;
	}

	if (multi && ids[idx]) { /* still some values to map */
		goto again;
	}

	ret = NT_STATUS_OK;

	/* mark all unknwon/expired ones as unmapped */
	for (i = 0; ids[i]; i++) {
		if (ids[i]->status != ID_MAPPED)
			ids[i]->status = ID_UNMAPPED;
	}

done:
	talloc_free(memctx);
	return ret;
}
Beispiel #2
0
static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
                                  TALLOC_CTX *mem_ctx,
                                  const struct dom_sid *domain_sid,
                                  uint32 *rids,
                                  size_t num_rids,
                                  char **pdomain_name,
                                  char ***pnames,
                                  enum lsa_SidType **ptypes)
{
    struct rpc_pipe_client *lsa_pipe;
    struct policy_handle lsa_policy;
    enum lsa_SidType *types = NULL;
    char *domain_name = NULL;
    char **names = NULL;
    TALLOC_CTX *tmp_ctx;
    NTSTATUS status, result;
    struct dcerpc_binding_handle *b = NULL;

    DEBUG(3,("sam_rids_to_names for %s\n", domain->name));

    ZERO_STRUCT(lsa_policy);

    /* Paranoia check */
    if (!sid_check_is_builtin(domain_sid) &&
            !sid_check_is_our_sam(domain_sid) &&
            !sid_check_is_unix_users(domain_sid) &&
            !sid_check_is_unix_groups(domain_sid) &&
            !sid_check_is_in_wellknown_domain(domain_sid)) {
        DEBUG(0, ("sam_rids_to_names: possible deadlock - trying to "
                  "lookup SID %s\n", sid_string_dbg(domain_sid)));
        return NT_STATUS_NONE_MAPPED;
    }

    tmp_ctx = talloc_stackframe();
    if (tmp_ctx == NULL) {
        return NT_STATUS_NO_MEMORY;
    }

    status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
    if (!NT_STATUS_IS_OK(status)) {
        goto done;
    }

    b = lsa_pipe->binding_handle;

    status = rpc_rids_to_names(tmp_ctx,
                               lsa_pipe,
                               &lsa_policy,
                               domain,
                               domain_sid,
                               rids,
                               num_rids,
                               &domain_name,
                               &names,
                               &types);
    if (!NT_STATUS_IS_OK(status)) {
        goto done;
    }

    if (pdomain_name) {
        *pdomain_name = talloc_move(mem_ctx, &domain_name);
    }

    if (ptypes) {
        *ptypes = talloc_move(mem_ctx, &types);
    }

    if (pnames) {
        *pnames = talloc_move(mem_ctx, &names);
    }

done:
    if (b && is_valid_policy_hnd(&lsa_policy)) {
        dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
    }

    TALLOC_FREE(tmp_ctx);
    return status;
}
Beispiel #3
0
int vfs_get_user_ntquota_list(files_struct *fsp, SMB_NTQUOTA_LIST **qt_list)
{
	struct passwd *usr;
	TALLOC_CTX *mem_ctx = NULL;

	if (!fsp||!fsp->conn||!qt_list)
		return (-1);

	*qt_list = NULL;

	if ((mem_ctx=talloc_init("SMB_USER_QUOTA_LIST"))==NULL) {
		DEBUG(0,("talloc_init() failed\n"));
		return (-1);
	}

	sys_setpwent();
	while ((usr = sys_getpwent()) != NULL) {
		SMB_NTQUOTA_STRUCT tmp_qt;
		SMB_NTQUOTA_LIST *tmp_list_ent;
		DOM_SID	sid;

		ZERO_STRUCT(tmp_qt);

		if (allready_in_quota_list((*qt_list),usr->pw_uid)) {
			DEBUG(5,("record for uid[%ld] allready in the list\n",(long)usr->pw_uid));
			continue;
		}

		uid_to_sid(&sid, usr->pw_uid);

		if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &tmp_qt)!=0) {
			DEBUG(5,("no quota entry for sid[%s] path[%s]\n",
				 sid_string_dbg(&sid),
				 fsp->conn->connectpath));
			continue;
		}

		DEBUG(15,("quota entry for id[%s] path[%s]\n",
			  sid_string_dbg(&sid), fsp->conn->connectpath));

		if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) {
			DEBUG(0,("TALLOC_ZERO() failed\n"));
			*qt_list = NULL;
			talloc_destroy(mem_ctx);
			return (-1);
		}

		if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) {
			DEBUG(0,("TALLOC_ZERO() failed\n"));
			*qt_list = NULL;
			talloc_destroy(mem_ctx);
			return (-1);
		}

		tmp_list_ent->uid = usr->pw_uid;
		memcpy(tmp_list_ent->quotas,&tmp_qt,sizeof(tmp_qt));
		tmp_list_ent->mem_ctx = mem_ctx;

		DLIST_ADD((*qt_list),tmp_list_ent);
		
	}
	sys_endpwent();

	return 0;
}
Beispiel #4
0
static NTSTATUS find_forced_group(bool force_user,
				  int snum, const char *username,
				  struct dom_sid *pgroup_sid,
				  gid_t *pgid)
{
	NTSTATUS result = NT_STATUS_NO_SUCH_GROUP;
	TALLOC_CTX *frame = talloc_stackframe();
	struct dom_sid group_sid;
	enum lsa_SidType type;
	char *groupname;
	bool user_must_be_member = False;
	gid_t gid;

	groupname = lp_force_group(talloc_tos(), snum);
	if (groupname == NULL) {
		DEBUG(1, ("talloc_strdup failed\n"));
		result = NT_STATUS_NO_MEMORY;
		goto done;
	}

	if (groupname[0] == '+') {
		user_must_be_member = True;
		groupname += 1;
	}

	groupname = talloc_string_sub(talloc_tos(), groupname,
				      "%S", lp_servicename(talloc_tos(), snum));
	if (groupname == NULL) {
		DEBUG(1, ("talloc_string_sub failed\n"));
		result = NT_STATUS_NO_MEMORY;
		goto done;
	}

	if (!lookup_name_smbconf(talloc_tos(), groupname,
			 LOOKUP_NAME_ALL|LOOKUP_NAME_GROUP,
			 NULL, NULL, &group_sid, &type)) {
		DEBUG(10, ("lookup_name_smbconf(%s) failed\n",
			   groupname));
		goto done;
	}

	if ((type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) &&
	    (type != SID_NAME_WKN_GRP)) {
		DEBUG(10, ("%s is a %s, not a group\n", groupname,
			   sid_type_lookup(type)));
		goto done;
	}

	if (!sid_to_gid(&group_sid, &gid)) {
		DEBUG(10, ("sid_to_gid(%s) for %s failed\n",
			   sid_string_dbg(&group_sid), groupname));
		goto done;
	}

	/*
	 * If the user has been forced and the forced group starts with a '+',
	 * then we only set the group to be the forced group if the forced
	 * user is a member of that group.  Otherwise, the meaning of the '+'
	 * would be ignored.
	 */

	if (force_user && user_must_be_member) {
		if (user_in_group_sid(username, &group_sid)) {
			sid_copy(pgroup_sid, &group_sid);
			*pgid = gid;
			DEBUG(3,("Forced group %s for member %s\n",
				 groupname, username));
		} else {
			DEBUG(0,("find_forced_group: forced user %s is not a member "
				"of forced group %s. Disallowing access.\n",
				username, groupname ));
			result = NT_STATUS_MEMBER_NOT_IN_GROUP;
			goto done;
		}
	} else {
		sid_copy(pgroup_sid, &group_sid);
		*pgid = gid;
		DEBUG(3,("Forced group %s\n", groupname));
	}

	result = NT_STATUS_OK;
 done:
	TALLOC_FREE(frame);
	return result;
}
Beispiel #5
0
/* Add a trusted domain out of a trusted domain cache
   entry
*/
static struct winbindd_domain *
add_trusted_domain_from_tdc(const struct winbindd_tdc_domain *tdc)
{
	struct winbindd_domain *domain;
	const char *alternative_name = NULL;
	const char **ignored_domains, **dom;
	int role = lp_server_role();
	const char *domain_name = tdc->domain_name;
	const struct dom_sid *sid = &tdc->sid;

	if (is_null_sid(sid)) {
		sid = NULL;
	}

	ignored_domains = lp_parm_string_list(-1, "winbind", "ignore domains", NULL);
	for (dom=ignored_domains; dom && *dom; dom++) {
		if (gen_fnmatch(*dom, domain_name) == 0) {
			DEBUG(2,("Ignoring domain '%s'\n", domain_name));
			return NULL;
		}
	}

	/* use alt_name if available to allow DNS lookups */

	if (tdc->dns_name && *tdc->dns_name) {
		alternative_name = tdc->dns_name;
	}

	/* We can't call domain_list() as this function is called from
	   init_domain_list() and we'll get stuck in a loop. */
	for (domain = _domain_list; domain; domain = domain->next) {
		if (strequal(domain_name, domain->name) ||
		    strequal(domain_name, domain->alt_name))
		{
			break;
		}

		if (alternative_name) {
			if (strequal(alternative_name, domain->name) ||
			    strequal(alternative_name, domain->alt_name))
			{
				break;
			}
		}

		if (sid != NULL) {
			if (dom_sid_equal(sid, &domain->sid)) {
				break;
			}
		}
	}

	if (domain != NULL) {
		/*
		 * We found a match on domain->name or
		 * domain->alt_name. Possibly update the SID
		 * if the stored SID was the NULL SID
		 * and return the matching entry.
		 */
		if ((sid != NULL)
		    && dom_sid_equal(&domain->sid, &global_sid_NULL)) {
			sid_copy( &domain->sid, sid );
		}
		return domain;
	}

	/* Create new domain entry */
	domain = talloc_zero(NULL, struct winbindd_domain);
	if (domain == NULL) {
		return NULL;
	}

	domain->children = talloc_zero_array(domain,
					     struct winbindd_child,
					     lp_winbind_max_domain_connections());
	if (domain->children == NULL) {
		TALLOC_FREE(domain);
		return NULL;
	}

	domain->name = talloc_strdup(domain, domain_name);
	if (domain->name == NULL) {
		TALLOC_FREE(domain);
		return NULL;
	}

	if (alternative_name) {
		domain->alt_name = talloc_strdup(domain, alternative_name);
		if (domain->alt_name == NULL) {
			TALLOC_FREE(domain);
			return NULL;
		}
	}

	domain->backend = NULL;
	domain->internal = is_internal_domain(sid);
	domain->sequence_number = DOM_SEQUENCE_NONE;
	domain->last_seq_check = 0;
	domain->initialized = false;
	domain->online = is_internal_domain(sid);
	domain->check_online_timeout = 0;
	domain->dc_probe_pid = (pid_t)-1;
	if (sid != NULL) {
		sid_copy(&domain->sid, sid);
	}
	domain->domain_flags = tdc->trust_flags;
	domain->domain_type = tdc->trust_type;
	domain->domain_trust_attribs = tdc->trust_attribs;

	/* Is this our primary domain ? */
	if (strequal(domain_name, get_global_sam_name()) &&
			(role != ROLE_DOMAIN_MEMBER)) {
		domain->primary = true;
	} else if (strequal(domain_name, lp_workgroup()) &&
			(role == ROLE_DOMAIN_MEMBER)) {
		domain->primary = true;
	}

	if (domain->primary) {
		if (role == ROLE_ACTIVE_DIRECTORY_DC) {
			domain->active_directory = true;
		}
		if (lp_security() == SEC_ADS) {
			domain->active_directory = true;
		}
	} else if (!domain->internal) {
		if (domain->domain_type == LSA_TRUST_TYPE_UPLEVEL) {
			domain->active_directory = true;
		}
	}

	/* Link to domain list */
	DLIST_ADD_END(_domain_list, domain);

	wcache_tdc_add_domain( domain );

	setup_domain_child(domain);

	DEBUG(2,
	      ("Added domain %s %s %s\n", domain->name, domain->alt_name,
	       !is_null_sid(&domain->sid) ? sid_string_dbg(&domain->sid) : ""));

	return domain;
}
Beispiel #6
0
static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name,
						  struct winbindd_methods *methods,
						  const struct dom_sid *sid)
{
	struct winbindd_domain *domain;
	const char *alternative_name = NULL;
	char *idmap_config_option;
	const char *param;
	const char **ignored_domains, **dom;
	int role = lp_server_role();

	ignored_domains = lp_parm_string_list(-1, "winbind", "ignore domains", NULL);
	for (dom=ignored_domains; dom && *dom; dom++) {
		if (gen_fnmatch(*dom, domain_name) == 0) {
			DEBUG(2,("Ignoring domain '%s'\n", domain_name));
			return NULL;
		}
	}

	/* use alt_name if available to allow DNS lookups */

	if (alt_name && *alt_name) {
		alternative_name = alt_name;
	}

	/* We can't call domain_list() as this function is called from
	   init_domain_list() and we'll get stuck in a loop. */
	for (domain = _domain_list; domain; domain = domain->next) {
		if (strequal(domain_name, domain->name) ||
		    strequal(domain_name, domain->alt_name))
		{
			break;
		}

		if (alternative_name && *alternative_name)
		{
			if (strequal(alternative_name, domain->name) ||
			    strequal(alternative_name, domain->alt_name))
			{
				break;
			}
		}

		if (sid)
		{
			if (is_null_sid(sid)) {
				continue;
			}

			if (dom_sid_equal(sid, &domain->sid)) {
				break;
			}
		}
	}

	if (domain != NULL) {
		/*
		 * We found a match on domain->name or
		 * domain->alt_name. Possibly update the SID
		 * if the stored SID was the NULL SID
		 * and return the matching entry.
		 */
		if ((sid != NULL)
		    && dom_sid_equal(&domain->sid, &global_sid_NULL)) {
			sid_copy( &domain->sid, sid );
		}
		return domain;
	}

	/* Create new domain entry */
	domain = talloc_zero(NULL, struct winbindd_domain);
	if (domain == NULL) {
		return NULL;
	}

	domain->children = talloc_zero_array(domain,
					     struct winbindd_child,
					     lp_winbind_max_domain_connections());
	if (domain->children == NULL) {
		TALLOC_FREE(domain);
		return NULL;
	}

	domain->name = talloc_strdup(domain, domain_name);
	if (domain->name == NULL) {
		TALLOC_FREE(domain);
		return NULL;
	}

	if (alternative_name) {
		domain->alt_name = talloc_strdup(domain, alternative_name);
		if (domain->alt_name == NULL) {
			TALLOC_FREE(domain);
			return NULL;
		}
	}

	domain->methods = methods;
	domain->backend = NULL;
	domain->internal = is_internal_domain(sid);
	domain->sequence_number = DOM_SEQUENCE_NONE;
	domain->last_seq_check = 0;
	domain->initialized = False;
	domain->online = is_internal_domain(sid);
	domain->check_online_timeout = 0;
	domain->dc_probe_pid = (pid_t)-1;
	if (sid) {
		sid_copy(&domain->sid, sid);
	}

	/* Is this our primary domain ? */
	if (strequal(domain_name, get_global_sam_name()) &&
			(role != ROLE_DOMAIN_MEMBER)) {
		domain->primary = true;
	} else if (strequal(domain_name, lp_workgroup()) &&
			(role == ROLE_DOMAIN_MEMBER)) {
		domain->primary = true;
	}

	if (domain->primary) {
		if (role == ROLE_ACTIVE_DIRECTORY_DC) {
			domain->active_directory = true;
		}
		if (lp_security() == SEC_ADS) {
			domain->active_directory = true;
		}
	}

	/* Link to domain list */
	DLIST_ADD_END(_domain_list, domain, struct winbindd_domain *);

	wcache_tdc_add_domain( domain );

	idmap_config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
					      domain->name);
	if (idmap_config_option == NULL) {
		DEBUG(0, ("talloc failed, not looking for idmap config\n"));
		goto done;
	}

	param = lp_parm_const_string(-1, idmap_config_option, "range", NULL);

	DEBUG(10, ("%s : range = %s\n", idmap_config_option,
		   param ? param : "not defined"));

	if (param != NULL) {
		unsigned low_id, high_id;
		if (sscanf(param, "%u - %u", &low_id, &high_id) != 2) {
			DEBUG(1, ("invalid range syntax in %s: %s\n",
				  idmap_config_option, param));
			goto done;
		}
		if (low_id > high_id) {
			DEBUG(1, ("invalid range in %s: %s\n",
				  idmap_config_option, param));
			goto done;
		}
		domain->have_idmap_config = true;
		domain->id_range_low = low_id;
		domain->id_range_high = high_id;
	}

done:

	setup_domain_child(domain);

	DEBUG(2,("Added domain %s %s %s\n",
		 domain->name, domain->alt_name,
		 &domain->sid?sid_string_dbg(&domain->sid):""));

	return domain;
}
static NTSTATUS display_sam_entry(TALLOC_CTX *mem_ctx,
				  enum netr_SamDatabaseID database_id,
				  struct netr_DELTA_ENUM *r,
				  struct samsync_context *ctx)
{
	union netr_DELTA_UNION u = r->delta_union;
	union netr_DELTA_ID_UNION id = r->delta_id_union;

	switch (r->delta_type) {
	case NETR_DELTA_DOMAIN:
		display_domain_info(u.domain);
		break;
	case NETR_DELTA_GROUP:
		display_group_info(id.rid, u.group);
		break;
	case NETR_DELTA_DELETE_GROUP:
		display_delete_group(id.rid);
		break;
	case NETR_DELTA_RENAME_GROUP:
		display_rename_group(id.rid, u.rename_group);
		break;
	case NETR_DELTA_USER:
		display_account_info(id.rid, u.user);
		break;
	case NETR_DELTA_DELETE_USER:
		display_delete_user(id.rid);
		break;
	case NETR_DELTA_RENAME_USER:
		display_rename_user(id.rid, u.rename_user);
		break;
	case NETR_DELTA_GROUP_MEMBER:
		display_group_mem_info(id.rid, u.group_member);
		break;
	case NETR_DELTA_ALIAS:
		display_alias_info(id.rid, u.alias);
		break;
	case NETR_DELTA_DELETE_ALIAS:
		display_delete_alias(id.rid);
		break;
	case NETR_DELTA_RENAME_ALIAS:
		display_rename_alias(id.rid, u.rename_alias);
		break;
	case NETR_DELTA_ALIAS_MEMBER:
		display_alias_mem(id.rid, u.alias_member);
		break;
	case NETR_DELTA_POLICY:
		printf("Policy: %s\n",
			sid_string_dbg(id.sid));
		break;
	case NETR_DELTA_TRUSTED_DOMAIN:
		printf("Trusted Domain: %s\n",
			u.trusted_domain->domain_name.string);
		break;
	case NETR_DELTA_DELETE_TRUST:
		printf("Delete Trust: %s\n",
			sid_string_dbg(id.sid));
		break;
	case NETR_DELTA_ACCOUNT:
		printf("Account: %s\n",
			sid_string_dbg(id.sid));
		break;
	case NETR_DELTA_DELETE_ACCOUNT:
		printf("Delete Account: %s\n",
			sid_string_dbg(id.sid));
		break;
	case NETR_DELTA_SECRET:
		printf("Secret: %s\n",
			id.name);
		break;
	case NETR_DELTA_DELETE_SECRET:
		printf("Delete Secret: %s\n",
			id.name);
		break;
	case NETR_DELTA_DELETE_GROUP2:
		printf("Delete Group2: %s\n",
			u.delete_group->account_name);
		break;
	case NETR_DELTA_DELETE_USER2:
		printf("Delete User2: %s\n",
			u.delete_user->account_name);
		break;
	case NETR_DELTA_MODIFY_COUNT:
		printf("sam sequence update: 0x%016llx\n",
			(unsigned long long) *u.modified_count);
		break;
#if 0
	/* The following types are recognised but not handled */
	case NETR_DELTA_POLICY:
		d_printf("NETR_DELTA_POLICY not handled\n");
		break;
	case NETR_DELTA_TRUSTED_DOMAIN:
		d_printf("NETR_DELTA_TRUSTED_DOMAIN not handled\n");
		break;
	case NETR_DELTA_ACCOUNT:
		d_printf("NETR_DELTA_ACCOUNT not handled\n");
		break;
	case NETR_DELTA_SECRET:
		d_printf("NETR_DELTA_SECRET not handled\n");
		break;
	case NETR_DELTA_MODIFY_COUNT:
		d_printf("NETR_DELTA_MODIFY_COUNT not handled\n");
		break;
	case NETR_DELTA_DELETE_TRUST:
		d_printf("NETR_DELTA_DELETE_TRUST not handled\n");
		break;
	case NETR_DELTA_DELETE_ACCOUNT:
		d_printf("NETR_DELTA_DELETE_ACCOUNT not handled\n");
		break;
	case NETR_DELTA_DELETE_SECRET:
		d_printf("NETR_DELTA_DELETE_SECRET not handled\n");
		break;
	case NETR_DELTA_DELETE_GROUP2:
		d_printf("NETR_DELTA_DELETE_GROUP2 not handled\n");
		break;
	case NETR_DELTA_DELETE_USER2:
		d_printf("NETR_DELTA_DELETE_USER2 not handled\n");
		break;
#endif
	default:
		printf("unknown delta type 0x%02x\n",
			r->delta_type);
		break;
	}

	return NT_STATUS_OK;
}
Beispiel #8
0
static bool smbacl4_fill_ace4(
	const struct smb_filename *filename,
	smbacl4_vfs_params *params,
	uid_t ownerUID,
	gid_t ownerGID,
	const struct security_ace *ace_nt, /* input */
	SMB_ACE4PROP_T *ace_v4 /* output */
)
{
	DEBUG(10, ("got ace for %s\n", sid_string_dbg(&ace_nt->trustee)));

	ZERO_STRUCTP(ace_v4);

	/* only ACCESS|DENY supported right now */
	ace_v4->aceType = ace_nt->type;

	ace_v4->aceFlags = map_windows_ace_flags_to_nfs4_ace_flags(
		ace_nt->flags);

	/* remove inheritance flags on files */
	if (VALID_STAT(filename->st) &&
	    !S_ISDIR(filename->st.st_ex_mode)) {
		DEBUG(10, ("Removing inheritance flags from a file\n"));
		ace_v4->aceFlags &= ~(SMB_ACE4_FILE_INHERIT_ACE|
				      SMB_ACE4_DIRECTORY_INHERIT_ACE|
				      SMB_ACE4_NO_PROPAGATE_INHERIT_ACE|
				      SMB_ACE4_INHERIT_ONLY_ACE);
	}

	ace_v4->aceMask = ace_nt->access_mask &
		(SEC_STD_ALL | SEC_FILE_ALL);

	se_map_generic(&ace_v4->aceMask, &file_generic_mapping);

	if (ace_v4->aceFlags!=ace_nt->flags)
		DEBUG(9, ("ace_v4->aceFlags(0x%x)!=ace_nt->flags(0x%x)\n",
			ace_v4->aceFlags, ace_nt->flags));

	if (ace_v4->aceMask!=ace_nt->access_mask)
		DEBUG(9, ("ace_v4->aceMask(0x%x)!=ace_nt->access_mask(0x%x)\n",
			ace_v4->aceMask, ace_nt->access_mask));

	if (dom_sid_equal(&ace_nt->trustee, &global_sid_World)) {
		ace_v4->who.special_id = SMB_ACE4_WHO_EVERYONE;
		ace_v4->flags |= SMB_ACE4_ID_SPECIAL;
	} else if (params->mode!=e_special &&
		   dom_sid_equal(&ace_nt->trustee,
				 &global_sid_Creator_Owner)) {
		DEBUG(10, ("Map creator owner\n"));
		ace_v4->who.special_id = SMB_ACE4_WHO_OWNER;
		ace_v4->flags |= SMB_ACE4_ID_SPECIAL;
		/* A non inheriting creator owner entry has no effect. */
		ace_v4->aceFlags |= SMB_ACE4_INHERIT_ONLY_ACE;
		if (!(ace_v4->aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE)
		    && !(ace_v4->aceFlags & SMB_ACE4_FILE_INHERIT_ACE)) {
			return false;
		}
	} else if (params->mode!=e_special &&
		   dom_sid_equal(&ace_nt->trustee,
				 &global_sid_Creator_Group)) {
		DEBUG(10, ("Map creator owner group\n"));
		ace_v4->who.special_id = SMB_ACE4_WHO_GROUP;
		ace_v4->flags |= SMB_ACE4_ID_SPECIAL;
		/* A non inheriting creator group entry has no effect. */
		ace_v4->aceFlags |= SMB_ACE4_INHERIT_ONLY_ACE;
		if (!(ace_v4->aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE)
		    && !(ace_v4->aceFlags & SMB_ACE4_FILE_INHERIT_ACE)) {
			return false;
		}
	} else {
		uid_t uid;
		gid_t gid;

		if (sid_to_gid(&ace_nt->trustee, &gid)) {
			ace_v4->aceFlags |= SMB_ACE4_IDENTIFIER_GROUP;
			ace_v4->who.gid = gid;
		} else if (sid_to_uid(&ace_nt->trustee, &uid)) {
			ace_v4->who.uid = uid;
		} else if (dom_sid_compare_domain(&ace_nt->trustee,
						  &global_sid_Unix_NFS) == 0) {
			return false;
		} else {
			DEBUG(1, ("nfs4_acls.c: file [%s]: could not "
				  "convert %s to uid or gid\n",
				  filename->base_name,
				  sid_string_dbg(&ace_nt->trustee)));
			return false;
		}
	}

	return true; /* OK */
}
Beispiel #9
0
static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx,
	smbacl4_vfs_params *params,
	struct SMB4ACL_T *acl, /* in */
	struct dom_sid *psid_owner, /* in */
	struct dom_sid *psid_group, /* in */
	bool is_directory, /* in */
	struct security_ace **ppnt_ace_list, /* out */
	int *pgood_aces /* out */
)
{
	struct SMB4ACE_T *aceint;
	struct security_ace *nt_ace_list = NULL;
	int good_aces = 0;

	DEBUG(10, ("%s entered\n", __func__));

	nt_ace_list = talloc_zero_array(mem_ctx, struct security_ace,
					2 * acl->naces);
	if (nt_ace_list==NULL)
	{
		DEBUG(10, ("talloc error with %d aces", acl->naces));
		errno = ENOMEM;
		return false;
	}

	for (aceint = acl->first; aceint != NULL; aceint = aceint->next) {
		uint32_t mask;
		struct dom_sid sid;
		SMB_ACE4PROP_T	*ace = &aceint->prop;
		uint32_t win_ace_flags;

		DEBUG(10, ("type: %d, iflags: %x, flags: %x, "
			   "mask: %x, who: %d\n",
			   ace->aceType, ace->flags,
			   ace->aceFlags, ace->aceMask, ace->who.id));

		if (ace->flags & SMB_ACE4_ID_SPECIAL) {
			switch (ace->who.special_id) {
			case SMB_ACE4_WHO_OWNER:
				sid_copy(&sid, psid_owner);
				break;
			case SMB_ACE4_WHO_GROUP:
				sid_copy(&sid, psid_group);
				break;
			case SMB_ACE4_WHO_EVERYONE:
				sid_copy(&sid, &global_sid_World);
				break;
			default:
				DEBUG(8, ("invalid special who id %d "
					"ignored\n", ace->who.special_id));
				continue;
			}
		} else {
			if (ace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP) {
				gid_to_sid(&sid, ace->who.gid);
			} else {
				uid_to_sid(&sid, ace->who.uid);
			}
		}
		DEBUG(10, ("mapped %d to %s\n", ace->who.id,
			   sid_string_dbg(&sid)));

		if (is_directory && (ace->aceMask & SMB_ACE4_ADD_FILE)) {
			ace->aceMask |= SMB_ACE4_DELETE_CHILD;
		}

		if (!is_directory && params->map_full_control) {
			/*
			 * Do we have all access except DELETE_CHILD
			 * (not caring about the delete bit).
			 */
			uint32_t test_mask = ((ace->aceMask|SMB_ACE4_DELETE|SMB_ACE4_DELETE_CHILD) &
						SMB_ACE4_ALL_MASKS);
			if (test_mask == SMB_ACE4_ALL_MASKS) {
				ace->aceMask |= SMB_ACE4_DELETE_CHILD;
			}
		}

		win_ace_flags = map_nfs4_ace_flags_to_windows_ace_flags(
			ace->aceFlags);
		if (!is_directory &&
		    (win_ace_flags & (SEC_ACE_FLAG_OBJECT_INHERIT|
				      SEC_ACE_FLAG_CONTAINER_INHERIT))) {
			/*
			 * GPFS sets inherits dir_inhert and file_inherit flags
			 * to files, too, which confuses windows, and seems to
			 * be wrong anyways. ==> Map these bits away for files.
			 */
			DEBUG(10, ("removing inherit flags from nfs4 ace\n"));
			win_ace_flags &= ~(SEC_ACE_FLAG_OBJECT_INHERIT|
					   SEC_ACE_FLAG_CONTAINER_INHERIT);
		}
		DEBUG(10, ("Windows mapped ace flags: 0x%x => 0x%x\n",
		      ace->aceFlags, win_ace_flags));

		mask = ace->aceMask;
		/* Windows clients expect SYNC on acls to
		   correctly allow rename. See bug #7909. */
		/* But not on DENY ace entries. See
		   bug #8442. */
		if(ace->aceType == SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE) {
			mask = ace->aceMask | SMB_ACE4_SYNCHRONIZE;
		}

		/* Mapping of owner@ and group@ to creator owner and
		   creator group. Keep old behavior in mode special. */
		if (params->mode != e_special &&
		    ace->flags & SMB_ACE4_ID_SPECIAL &&
		    (ace->who.special_id == SMB_ACE4_WHO_OWNER ||
		     ace->who.special_id == SMB_ACE4_WHO_GROUP)) {
			DEBUG(10, ("Map special entry\n"));
			if (!(win_ace_flags & SEC_ACE_FLAG_INHERIT_ONLY)) {
				uint32_t win_ace_flags_current;
				DEBUG(10, ("Map current sid\n"));
				win_ace_flags_current = win_ace_flags &
					~(SEC_ACE_FLAG_OBJECT_INHERIT |
					  SEC_ACE_FLAG_CONTAINER_INHERIT);
				init_sec_ace(&nt_ace_list[good_aces++], &sid,
					     ace->aceType, mask,
					     win_ace_flags_current);
			}
			if (ace->who.special_id == SMB_ACE4_WHO_OWNER &&
			    win_ace_flags & (SEC_ACE_FLAG_OBJECT_INHERIT |
					     SEC_ACE_FLAG_CONTAINER_INHERIT)) {
				uint32_t win_ace_flags_creator;
				DEBUG(10, ("Map creator owner\n"));
				win_ace_flags_creator = win_ace_flags |
					SMB_ACE4_INHERIT_ONLY_ACE;
				init_sec_ace(&nt_ace_list[good_aces++],
					     &global_sid_Creator_Owner,
					     ace->aceType, mask,
					     win_ace_flags_creator);
			}
			if (ace->who.special_id == SMB_ACE4_WHO_GROUP &&
			    win_ace_flags & (SEC_ACE_FLAG_OBJECT_INHERIT |
					     SEC_ACE_FLAG_CONTAINER_INHERIT)) {
				uint32_t win_ace_flags_creator;
				DEBUG(10, ("Map creator owner group\n"));
				win_ace_flags_creator = win_ace_flags |
					SMB_ACE4_INHERIT_ONLY_ACE;
				init_sec_ace(&nt_ace_list[good_aces++],
					     &global_sid_Creator_Group,
					     ace->aceType, mask,
					     win_ace_flags_creator);
			}
		} else {
			DEBUG(10, ("Map normal sid\n"));
			init_sec_ace(&nt_ace_list[good_aces++], &sid,
				     ace->aceType, mask,
				     win_ace_flags);
		}
	}

	nt_ace_list = talloc_realloc(mem_ctx, nt_ace_list, struct security_ace,
				     good_aces);

	/* returns a NULL ace list when good_aces is zero. */
	if (good_aces && nt_ace_list == NULL) {
		DEBUG(10, ("realloc error with %d aces", good_aces));
		errno = ENOMEM;
		return false;
	}

	*ppnt_ace_list = nt_ace_list;
	*pgood_aces = good_aces;

	return true;
}