Beispiel #1
0
WERROR _wkssvc_NetWkstaGetInfo(struct pipes_struct *p,
			       struct wkssvc_NetWkstaGetInfo *r)
{
	switch (r->in.level) {
	case 100:
		/* Level 100 can be allowed from anyone including anonymous
		 * so no access checks are needed for this case */
		r->out.info->info100 = create_wks_info_100(p->mem_ctx);
		if (r->out.info->info100 == NULL) {
			return WERR_NOMEM;
		}
		break;
	case 101:
		/* Level 101 can be allowed from any logged in user */
		if (!nt_token_check_sid(&global_sid_Authenticated_Users,
					p->session_info->security_token)) {
			DEBUG(1,("User not allowed for NetWkstaGetInfo level "
				 "101\n"));
			DEBUGADD(3,(" - does not have sid for Authenticated "
				    "Users %s:\n",
				    sid_string_dbg(
					    &global_sid_Authenticated_Users)));
			security_token_debug(DBGC_CLASS, 3,
					    p->session_info->security_token);
			return WERR_ACCESS_DENIED;
		}
		r->out.info->info101 = create_wks_info_101(p->mem_ctx);
		if (r->out.info->info101 == NULL) {
			return WERR_NOMEM;
		}
		break;
	case 102:
		/* Level 102 Should only be allowed from a domain administrator */
		if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
					p->session_info->security_token)) {
			DEBUG(1,("User not allowed for NetWkstaGetInfo level "
				 "102\n"));
			DEBUGADD(3,(" - does not have sid for Administrators "
				    "group %s, sids are:\n",
				    sid_string_dbg(&global_sid_Builtin_Administrators)));
			security_token_debug(DBGC_CLASS, 3,
					    p->session_info->security_token);
			return WERR_ACCESS_DENIED;
		}
		r->out.info->info102 = create_wks_info_102(p->mem_ctx);
		if (r->out.info->info102 == NULL) {
			return WERR_NOMEM;
		}
		break;
	default:
		return WERR_UNKNOWN_LEVEL;
	}

	return WERR_OK;
}
Beispiel #2
0
/**
 * prints a struct auth_session_info security token to debug output.
 */
void auth_session_info_debug(int dbg_lev,
                             const struct auth_session_info *session_info)
{
    if (!session_info) {
        DEBUG(dbg_lev, ("Session Info: (NULL)\n"));
        return;
    }

    security_token_debug(0, dbg_lev, session_info->security_token);
}
Beispiel #3
0
void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, const struct security_token *token)
{
	struct sec_ctx *ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx];

	/* Set the security context */

	DEBUG(4, ("setting sec ctx (%u, %u) - sec_ctx_stack_ndx = %d\n", 
		(unsigned int)uid, (unsigned int)gid, sec_ctx_stack_ndx));

	security_token_debug(DBGC_CLASS, 5, token);
	debug_unix_user_token(DBGC_CLASS, 5, uid, gid, ngroups, groups);

	/* Change uid, gid and supplementary group list. */
	set_unix_security_ctx(uid, gid, ngroups, groups);

	ctx_p->ut.ngroups = ngroups;

	SAFE_FREE(ctx_p->ut.groups);
	if (token && (token == ctx_p->token)) {
		smb_panic("DUPLICATE_TOKEN");
	}

	TALLOC_FREE(ctx_p->token);

	if (ngroups) {
		ctx_p->ut.groups = (gid_t *)memdup(groups,
						   sizeof(gid_t) * ngroups);
		if (!ctx_p->ut.groups) {
			smb_panic("memdup failed");
		}
	} else {
		ctx_p->ut.groups = NULL;
	}

	if (token) {
		ctx_p->token = dup_nt_token(NULL, token);
		if (!ctx_p->token) {
			smb_panic("dup_nt_token failed");
		}
	} else {
		ctx_p->token = NULL;
	}

	ctx_p->ut.uid = uid;
	ctx_p->ut.gid = gid;

	/* Update current_user stuff */

	current_user.ut.uid = uid;
	current_user.ut.gid = gid;
	current_user.ut.ngroups = ngroups;
	current_user.ut.groups = groups;
	current_user.nt_user_token = ctx_p->token;
}
Beispiel #4
0
/* 
  drsuapi_DsReplicaGetInfo 
*/
static WERROR dcesrv_drsuapi_DsReplicaGetInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
		       struct drsuapi_DsReplicaGetInfo *r)
{
	enum security_user_level level;

	if (!lp_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL,
			 "drs", "disable_sec_check", false)) {
		level = security_session_user_level(dce_call->conn->auth_state.session_info);
		if (level < SECURITY_ADMINISTRATOR) {
			DEBUG(1,(__location__ ": Administrator access required for DsReplicaGetInfo\n"));
			security_token_debug(2, dce_call->conn->auth_state.session_info->security_token);
			return WERR_DS_DRA_ACCESS_DENIED;
		}
	}

	dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx, r, NDR_DRSUAPI_DSREPLICAGETINFO,
				     &ndr_table_drsuapi, "kccsrv", "DsReplicaGetInfo");

	return WERR_OK;
}
Beispiel #5
0
WERROR _wkssvc_NetWkstaEnumUsers(struct pipes_struct *p,
				 struct wkssvc_NetWkstaEnumUsers *r)
{
	/* This with any level should only be allowed from a domain administrator */
	if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
				p->session_info->security_token)) {
		DEBUG(1,("User not allowed for NetWkstaEnumUsers\n"));
		DEBUGADD(3,(" - does not have sid for Administrators group "
			    "%s\n", sid_string_dbg(
				    &global_sid_Builtin_Administrators)));
		security_token_debug(DBGC_CLASS, 3, p->session_info->security_token);
		return WERR_ACCESS_DENIED;
	}

	switch (r->in.info->level) {
	case 0:
		r->out.info->ctr.user0 = create_enum_users0(p->mem_ctx);
		if (r->out.info->ctr.user0 == NULL) {
			return WERR_NOMEM;
		}
		r->out.info->level = r->in.info->level;
		*r->out.entries_read = r->out.info->ctr.user0->entries_read;
		*r->out.resume_handle = 0;
		break;
	case 1:
		r->out.info->ctr.user1 = create_enum_users1(p->mem_ctx);
		if (r->out.info->ctr.user1 == NULL) {
			return WERR_NOMEM;
		}
		r->out.info->level = r->in.info->level;
		*r->out.entries_read = r->out.info->ctr.user1->entries_read;
		*r->out.resume_handle = 0;
		break;
	default:
		return WERR_UNKNOWN_LEVEL;
	}

	return WERR_OK;
}
Beispiel #6
0
NTSTATUS create_local_token(struct auth_serversupplied_info *server_info)
{
	struct security_token *t;
	NTSTATUS status;
	size_t i;
	struct dom_sid tmp_sid;
	struct wbcUnixId *ids;

	/*
	 * If winbind is not around, we can not make much use of the SIDs the
	 * domain controller provided us with. Likewise if the user name was
	 * mapped to some local unix user.
	 */

	if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
	    (server_info->nss_token)) {
		status = create_token_from_username(server_info,
						    server_info->unix_name,
						    server_info->guest,
						    &server_info->utok.uid,
						    &server_info->utok.gid,
						    &server_info->unix_name,
						    &server_info->security_token);

	} else {
		status = create_local_nt_token_from_info3(server_info,
							  server_info->guest,
							  server_info->info3,
							  &server_info->extra,
							  &server_info->security_token);
	}

	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	/* Convert the SIDs to gids. */

	server_info->utok.ngroups = 0;
	server_info->utok.groups = NULL;

	t = server_info->security_token;

	ids = TALLOC_ARRAY(talloc_tos(), struct wbcUnixId,
			   t->num_sids);
	if (ids == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	if (!sids_to_unix_ids(t->sids, t->num_sids, ids)) {
		TALLOC_FREE(ids);
		return NT_STATUS_NO_MEMORY;
	}

	/* Start at index 1, where the groups start. */

	for (i=1; i<t->num_sids; i++) {

		if (ids[i].type != WBC_ID_TYPE_GID) {
			DEBUG(10, ("Could not convert SID %s to gid, "
				   "ignoring it\n",
				   sid_string_dbg(&t->sids[i])));
			continue;
		}
		if (!add_gid_to_array_unique(server_info, ids[i].id.gid,
					     &server_info->utok.groups,
					     &server_info->utok.ngroups)) {
			return NT_STATUS_NO_MEMORY;
		}
	}

	/*
	 * Add the "Unix Group" SID for each gid to catch mapped groups
	 * and their Unix equivalent.  This is to solve the backwards
	 * compatibility problem of 'valid users = +ntadmin' where
	 * ntadmin has been paired with "Domain Admins" in the group
	 * mapping table.  Otherwise smb.conf would need to be changed
	 * to 'valid user = "******"'.  --jerry
	 *
	 * For consistency we also add the "Unix User" SID,
	 * so that the complete unix token is represented within
	 * the nt token.
	 */

	uid_to_unix_users_sid(server_info->utok.uid, &tmp_sid);

	add_sid_to_array_unique(server_info->security_token, &tmp_sid,
				&server_info->security_token->sids,
				&server_info->security_token->num_sids);

	for ( i=0; i<server_info->utok.ngroups; i++ ) {
		gid_to_unix_groups_sid(server_info->utok.groups[i], &tmp_sid);
		add_sid_to_array_unique(server_info->security_token, &tmp_sid,
					&server_info->security_token->sids,
					&server_info->security_token->num_sids);
	}

	security_token_debug(DBGC_AUTH, 10, server_info->security_token);
	debug_unix_user_token(DBGC_AUTH, 10,
			      server_info->utok.uid,
			      server_info->utok.gid,
			      server_info->utok.ngroups,
			      server_info->utok.groups);

	status = log_nt_token(server_info->security_token);
	return status;
}
Beispiel #7
0
/*
  form a security_unix_token from the current security_token
*/
NTSTATUS security_token_to_unix_token(TALLOC_CTX *mem_ctx,
				      struct wbc_context *wbc_ctx,
				      struct security_token *token,
				      struct security_unix_token **sec)
{
	uint32_t s, g;
	NTSTATUS status;
	struct id_map *ids;
	struct composite_context *ctx;

	/* we can't do unix security without a user and group */
	if (token->num_sids < 2) {
		return NT_STATUS_ACCESS_DENIED;
	}

	*sec = talloc_zero(mem_ctx, struct security_unix_token);
	if (*sec == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	ids = talloc_zero_array(mem_ctx, struct id_map, token->num_sids);
	NT_STATUS_HAVE_NO_MEMORY(ids);

	for (s=0; s < token->num_sids; s++) {
		ids[s].sid = &token->sids[s];
		ids[s].status = ID_UNKNOWN;
	}

	ctx = wbc_sids_to_xids_send(wbc_ctx, ids, token->num_sids, ids);
	NT_STATUS_HAVE_NO_MEMORY(ctx);

	status = wbc_sids_to_xids_recv(ctx, &ids);
	NT_STATUS_NOT_OK_RETURN(status);

	g = token->num_sids;
	if (ids[0].xid.type != ID_TYPE_BOTH) {
		g--;
	}
	(*sec)->ngroups = g;
	(*sec)->groups = talloc_array(*sec, gid_t, (*sec)->ngroups);
	NT_STATUS_HAVE_NO_MEMORY((*sec)->groups);

	g=0;
	if (ids[0].xid.type == ID_TYPE_BOTH) {
		(*sec)->uid = ids[0].xid.id;
		(*sec)->groups[g] = ids[0].xid.id;
		g++;
	} else if (ids[0].xid.type == ID_TYPE_UID) {
		(*sec)->uid = ids[0].xid.id;
	} else {
		char *sid_str = dom_sid_string(mem_ctx, ids[0].sid);
		DEBUG(0, ("Unable to convert first SID (%s) in user token to a UID.  Conversion was returned as type %d, full token:\n",
			  sid_str, (int)ids[0].xid.type));
		security_token_debug(0, 0, token);
		talloc_free(sid_str);
		return NT_STATUS_INVALID_SID;
	}

	if (ids[1].xid.type == ID_TYPE_BOTH ||
	    ids[1].xid.type == ID_TYPE_GID) {
		(*sec)->gid = ids[1].xid.id;
		(*sec)->groups[g] = ids[1].xid.id;
		g++;
	} else {
		char *sid_str = dom_sid_string(mem_ctx, ids[1].sid);
		DEBUG(0, ("Unable to convert second SID (%s) in user token to a GID.  Conversion was returned as type %d, full token:\n",
			  sid_str, (int)ids[1].xid.type));
		security_token_debug(0, 0, token);
		talloc_free(sid_str);
		return NT_STATUS_INVALID_SID;
	}

	for (s=2; s < token->num_sids; s++) {
		if (ids[s].xid.type == ID_TYPE_BOTH ||
		    ids[s].xid.type == ID_TYPE_GID) {
			(*sec)->groups[g] = ids[s].xid.id;
			g++;
		} else {
			char *sid_str = dom_sid_string(mem_ctx, ids[s].sid);
			DEBUG(0, ("Unable to convert SID (%s) at index %u in user token to a GID.  Conversion was returned as type %d, full token:\n",
				  sid_str, (unsigned int)s, (int)ids[s].xid.type));
			security_token_debug(0, 0, token);
			talloc_free(sid_str);
			return NT_STATUS_INVALID_SID;
		}
	}

	DEBUG(5, ("Successfully converted security token to a unix token:"));
	security_token_debug(0, 5, token);
	TALLOC_FREE(ids);

	return NT_STATUS_OK;
}
Beispiel #8
0
NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
			    const struct auth_serversupplied_info *server_info,
			    DATA_BLOB *session_key,
			    const char *smb_username, /* for ->sanitized_username, for %U subs */
			    struct auth_session_info **session_info_out)
{
	struct security_token *t;
	NTSTATUS status;
	size_t i;
	struct dom_sid tmp_sid;
	struct auth_session_info *session_info;
	struct unixid *ids;
	fstring tmp;

	/* Ensure we can't possible take a code path leading to a
	 * null defref. */
	if (!server_info) {
		return NT_STATUS_LOGON_FAILURE;
	}

	session_info = talloc_zero(mem_ctx, struct auth_session_info);
	if (!session_info) {
		return NT_STATUS_NO_MEMORY;
	}

	session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
	if (!session_info->unix_token) {
		TALLOC_FREE(session_info);
		return NT_STATUS_NO_MEMORY;
	}

	session_info->unix_token->uid = server_info->utok.uid;
	session_info->unix_token->gid = server_info->utok.gid;

	session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
	if (!session_info->unix_info) {
		TALLOC_FREE(session_info);
		return NT_STATUS_NO_MEMORY;
	}

	session_info->unix_info->unix_name = talloc_strdup(session_info, server_info->unix_name);
	if (!session_info->unix_info->unix_name) {
		TALLOC_FREE(session_info);
		return NT_STATUS_NO_MEMORY;
	}

	/* This is a potentially untrusted username for use in %U */
	alpha_strcpy(tmp, smb_username, ". _-$", sizeof(tmp));
	session_info->unix_info->sanitized_username =
				talloc_strdup(session_info->unix_info, tmp);

	if (session_key) {
		data_blob_free(&session_info->session_key);
		session_info->session_key = data_blob_talloc(session_info,
								  session_key->data,
								  session_key->length);
		if (!session_info->session_key.data && session_key->length) {
			return NT_STATUS_NO_MEMORY;
		}
	} else {
		session_info->session_key = data_blob_talloc( session_info, server_info->session_key.data,
							      server_info->session_key.length);
	}

	/* We need to populate session_info->info with the information found in server_info->info3 */
	status = make_user_info_SamBaseInfo(session_info, "", &server_info->info3->base,
					    server_info->guest == false,
					    &session_info->info);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
		TALLOC_FREE(session_info);
		return status;
	}

	if (server_info->security_token) {
		/* Just copy the token, it has already been finalised
		 * (nasty hack to support a cached guest/system session_info
		 */

		session_info->security_token = dup_nt_token(session_info, server_info->security_token);
		if (!session_info->security_token) {
			TALLOC_FREE(session_info);
			return NT_STATUS_NO_MEMORY;
		}

		session_info->unix_token->ngroups = server_info->utok.ngroups;
		if (server_info->utok.ngroups != 0) {
			session_info->unix_token->groups = (gid_t *)talloc_memdup(
				session_info->unix_token, server_info->utok.groups,
				sizeof(gid_t)*session_info->unix_token->ngroups);
		} else {
			session_info->unix_token->groups = NULL;
		}

		*session_info_out = session_info;
		return NT_STATUS_OK;
	}

	/*
	 * If winbind is not around, we can not make much use of the SIDs the
	 * domain controller provided us with. Likewise if the user name was
	 * mapped to some local unix user.
	 */

	if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
	    (server_info->nss_token)) {
		char *found_username = NULL;
		status = create_token_from_username(session_info,
						    server_info->unix_name,
						    server_info->guest,
						    &session_info->unix_token->uid,
						    &session_info->unix_token->gid,
						    &found_username,
						    &session_info->security_token);
		if (NT_STATUS_IS_OK(status)) {
			session_info->unix_info->unix_name = found_username;
		}
	} else {
		status = create_local_nt_token_from_info3(session_info,
							  server_info->guest,
							  server_info->info3,
							  &server_info->extra,
							  &session_info->security_token);
	}

	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	/* Convert the SIDs to gids. */

	session_info->unix_token->ngroups = 0;
	session_info->unix_token->groups = NULL;

	t = session_info->security_token;

	ids = talloc_array(talloc_tos(), struct unixid,
			   t->num_sids);
	if (ids == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	if (!sids_to_unixids(t->sids, t->num_sids, ids)) {
		TALLOC_FREE(ids);
		return NT_STATUS_NO_MEMORY;
	}

	for (i=0; i<t->num_sids; i++) {

		if (i == 0 && ids[i].type != ID_TYPE_BOTH) {
			continue;
		}

		if (ids[i].type != ID_TYPE_GID &&
		    ids[i].type != ID_TYPE_BOTH) {
			DEBUG(10, ("Could not convert SID %s to gid, "
				   "ignoring it\n",
				   sid_string_dbg(&t->sids[i])));
			continue;
		}
		if (!add_gid_to_array_unique(session_info, ids[i].id,
					     &session_info->unix_token->groups,
					     &session_info->unix_token->ngroups)) {
			return NT_STATUS_NO_MEMORY;
		}
	}

	/*
	 * Add the "Unix Group" SID for each gid to catch mapped groups
	 * and their Unix equivalent.  This is to solve the backwards
	 * compatibility problem of 'valid users = +ntadmin' where
	 * ntadmin has been paired with "Domain Admins" in the group
	 * mapping table.  Otherwise smb.conf would need to be changed
	 * to 'valid user = "******"'.  --jerry
	 *
	 * For consistency we also add the "Unix User" SID,
	 * so that the complete unix token is represented within
	 * the nt token.
	 */

	uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);

	add_sid_to_array_unique(session_info->security_token, &tmp_sid,
				&session_info->security_token->sids,
				&session_info->security_token->num_sids);

	for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
		gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
		add_sid_to_array_unique(session_info->security_token, &tmp_sid,
					&session_info->security_token->sids,
					&session_info->security_token->num_sids);
	}

	security_token_debug(DBGC_AUTH, 10, session_info->security_token);
	debug_unix_user_token(DBGC_AUTH, 10,
			      session_info->unix_token->uid,
			      session_info->unix_token->gid,
			      session_info->unix_token->ngroups,
			      session_info->unix_token->groups);

	status = log_nt_token(session_info->security_token);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	*session_info_out = session_info;
	return NT_STATUS_OK;
}